Live data from Hacker News

Best practices for REST API design (2020)

stackoverflow.blog

251–260 of 273 posts

Re: Best practices for REST API design (2020)

#251
post #159

Most of these best practices forget the hard parts of JSON/REST APIs: - How to handle date and time incl. time zones - JSON has no data type for that - Handling of numbers (JSON only has double, which does not fit most cases) - Defined and parseable error responses (rfc 7807 plus extra fields for details) - Localization - do you send translated texts or just error codes? - How to handle updates? Overwrite every field…

Send ISO date/time in utc. Send numbers as strings. you should be treating this as hostile in your backend anyways, and checking it. Send both an error code, and a string in simple english, or whatever your most common developer language is. If you care about only updating certain fields, track changes and only send those fields to the backend. These arn't really that hard.

Should we put the error code in the http status code and status line, or in the response body? We’re having a great debate at work and it’s been a blast mapping business logic errors to closest http status code spiritual animal. The Dean of the REST Engineering Directorship has decreed a bit of both, but most of The Unwashed (front end developers) are revolting on this matter insisting it all maps to a red-tinted “Sorry, reboot and try again” toast.

In other news we’re suspecting transactions are on horizon. Half the backend team are in denial, the other half are busy trying to figure out the most pleasant place to install decidedly “unRESTy URLs” for them. Somebody already set themselves on fire over PUT/POST for that.

Re: Best practices for REST API design (2020)

#252
post #220

Earlier quoted context omitted.

Many of the numbers we use day to day are more like strings than actual integers, though. What sense does it make to divide by a zip code, or two add two zip codes together for instance?

This. Just because something contains numbers doesn't mean that it's numeric. Times aren't numbers because 6pm * 7am doesn't yield a meaningful result. Same thing with serial numbers, VIN numbers, building floor numbers, phone numbers, etc. All of those should always be strings, because performing "math" on them wouldn't yield meaningful results.

I work in ecommerce and deal with this issue a TON. I see it in things like GTIN/UPC or tracking numbers.

Re: Best practices for REST API design (2020)

#253
post #120

Earlier quoted context omitted.

What is the usefulness of this feature? The only advantage I see is that your clients can choose the format they want to work with, but since the serialization format is just a message format that has no impact on the code, and that most of them have a bijective transformation between them, I don't see the point. If it feels like a lot of work (Or the added complexity of a moving part, if using the tool you linked) f…

If you don't care about others using your API, then don't do it. If you do, follow the standard which says you SHOULD have a Content-Type if there is a body to your response.

My comment was about whether it's worth supporting multiple values for the "Accept" header, not the "Content-Type" header.

Re: Best practices for REST API design (2020)

#254

Earlier quoted context omitted.

If doesn't exist means it has been removed: 410 Gone, if doesn't exist means not yet created: 404 Not Found. I can't think for other types of not existing, or why you'd need to differentiate between them.

Say I have an API with a path of /customer/ . I call /customer/235235 and customer 235235 doesn't exist. That's a 404, resource not found. But say I make an uncaught error with the path and call /cutsomer/235235. That also is a 404, resource not found. It really depends on what you want the word "resource" to mean. It gets a bit more complex if you have a simplistic website with an API service both on the same server…

I've seen this type of reply in previous posts on this thread, and I am baffled at the fact that people seem to have their downstream users be much closer to the API than I think it's safe.

To answer the specific question /cutsomer/123 should never be hit in a production application, unless your user actually inputs that, so treating it differently is just overhead that gives no benefit.

Also for the "both on the same server" scenario, you can make a pretty good assumption if a user agent is a browser or an API client, so you can present the right output to the right one. The accept header is the simplest method I can think of.

Re: Best practices for REST API design (2020)

#255
post #250

Earlier quoted context omitted.

> This article doesn't mention linking at all, which is at the heart of REST. Please, just don't do it . Yes, I read the dissertation. It's just not a good idea, it has never given me any practical use whatsoever and has always made dealing with the API more annoying. > Most of it is just standard JSON-over-HTTP stuff that's implemented in a variety of frameworks and libraries. Yes, and we call that REST or RESTful a…

> Please, just don't do it. Yes, I read the dissertation. It's just not a good idea, it has never given me any practical use whatsoever and has always made dealing with the API more annoying. If you believe REST is not a good idea then you never had to deal with versioning and struggling to keep clients and servers you don't own to play nice. Asserting that something like REST has no practical purpose is asserting th…

>If you believe REST is not a good idea then you never had to deal with versioning and struggling to keep clients and servers you don't own to play nice.

Sincere question: how does HATEOAS helps with this?

The only thing that HATEOAS helps with, is when the URL pointing to an entity changes, which is the most simplest change someone can make to its API.

But if an API ever changes the relationships between entities (new entities, 1-1 relationship changed to a 1-m relationship, ...) then HATEOAS won't help at all. You'll still need to change the logic of your client to take into account the modifications.

I've always felt like nobody bothered supporting HATEOAS because it's practically useless. The only use-case where it can be used is if you want your API to be crawled by a search engine. Then the search engine could crawl between entities thanks to the links you provide.

Re: Best practices for REST API design (2020)

#256
post #186

Earlier quoted context omitted.

One reason could be that it's easy to think that a "number" is sanely typed, while you almost never want a double - not for quantity, not for price, etc. So you're going to cast to some (big) integer anyway...

In languages with reasonable number types (i.e. not JS), the parsers are typically able to produce integers, or even BigDecimal, out of a JSON number, without going through double.

I guess I feel returning error invalid integer for a valid json double is a bit wierd - but I guess it's not technicallyaany worse than "could not parse string as integer. It's more that it is expected that strings hold" other" data, like timestamps, while one might expect a double to hold only (but also any) doubles.

Re: Best practices for REST API design (2020)

#257
post #220

Earlier quoted context omitted.

> Send numbers as string [...] Why? Why not send a number as number (double) and treat it as hostile in the backend? I dislike sending numbers as string because I think the different data types exist for a reason.

Many of the numbers we use day to day are more like strings than actual integers, though. What sense does it make to divide by a zip code, or two add two zip codes together for instance?

Many != All

So prices are numbers (if supplied in cents, the smallest unit). There is length/depth/height/weight/... A lot of things are actual numbers. Why supply them as string?

I agree partially with you but think ZIP are a very bad example because a zip itself may also contain letters.

Re: Best practices for REST API design (2020)

#258
post #220

Earlier quoted context omitted.

Many of the numbers we use day to day are more like strings than actual integers, though. What sense does it make to divide by a zip code, or two add two zip codes together for instance?

This. Just because something contains numbers doesn't mean that it's numeric. Times aren't numbers because 6pm * 7am doesn't yield a meaningful result. Same thing with serial numbers, VIN numbers, building floor numbers, phone numbers, etc. All of those should always be strings, because performing "math" on them wouldn't yield meaningful results.

While I basically agree, there‘s a difference between „always send numbers as string“ and „send something that looks like a number but is actually a string as a string“.

Why should i send a dimension as a string? How am I going to calculate the volume from 3 strings?

Re: Best practices for REST API design (2020)

#259

Earlier quoted context omitted.

It depends on performance requirements. Either ask them to retrieve the entire objects, or expose a new endpoint to retrieve the filtered list in an optimal way. API consumers definitely aren't the ones who should be thinking about something like joining behavior, since GraphQL doesn't give nearly enough control to achieve performant joining. Basic filtering can also be easily achieved with ad-hoc methods, such as qu…

No need for it, from your perspective, sure. It totally solves a lot of shortcomings your API is forcing on its consumers though.

In general, my consumers don't want to learn my API. If they find shortcomings, they don't want to work around them by learning to query my bad models, they will call and complain that my model is bad and that I have to fix it in the next version or they'll look elsewhere.

At least, this has been our experience with B2B software sales.

Of course, YMMV depending on market etc.

Re: Best practices for REST API design (2020)

#260
post #250

Earlier quoted context omitted.

> Please, just don't do it. Yes, I read the dissertation. It's just not a good idea, it has never given me any practical use whatsoever and has always made dealing with the API more annoying. If you believe REST is not a good idea then you never had to deal with versioning and struggling to keep clients and servers you don't own to play nice. Asserting that something like REST has no practical purpose is asserting th…

>If you believe REST is not a good idea then you never had to deal with versioning and struggling to keep clients and servers you don't own to play nice. Sincere question: how does HATEOAS helps with this? The only thing that HATEOAS helps with, is when the URL pointing to an entity changes, which is the most simplest change someone can make to its API. But if an API ever changes the relationships between entities (n…

> Sincere question: how does HATEOAS helps with this?

The whole point of HATEOAS is to address this. This is pretty much why it was developed and presented. Why on earth is anyone discussing REST not picking up on it's reason to exist?

> The only thing that HATEOAS helps with, is when the URL pointing to an entity changes, which is the most simplest change someone can make to its API.

It really isn't. At all. You're somehow missing the whole point of a resource-based architecture, let alone REST.

The whole point is that there are no fixed paths. At all. All there is is resources, whose representation might vary in shape and form, which are made to be discoverable by providing semantic descriptions of said resources. With REST you provide resources and metadata that points to representations of those resources. With REST your clients do not care about endpoints other than a root one, and resources. The resto of the process consists of tracking resource representations that you want, and you do not care where they are. At all.

This sort of profound misconception of what REST is supposed to be is the reason why somehow some people believe that it's reasonable to slap the REST label on APIs just because they churn out JSON. You can't. REST is based on design constraints that address a problem which these APIs fail to address at a fundamental level.

Post reply on HN