Live data from Hacker News

Best practices for REST API design (2020)

stackoverflow.blog

181–190 of 273 posts

Re: Best practices for REST API design (2020)

#181

Earlier quoted context omitted.

The problem with GraphQL is on the front end. Suddenly, the FE team becomes responsible for understanding the entire data model, which resources can be joined together, by what keys, and what is actually performant vs what isn't. Instead of doing a simple GET /a/b/1/c and presenting that data structure, they now need to define a query, think about what resources to pull into that query etc. If the query ends up being…

that's an interesting point! And the graphql basically obscures a mental model over a broad abstraction, so it's impossible to know exactly what's going on without going through and actually reading the BE code itself. Thanks for the perspective.

I hit this problem when contemplating exposing the API of the application I work on to customers, to be used in their automation scripts.

We quickly realized that expecting them to learn our data model and how to use it efficiently would be much more complicated than exposing every plausible use-case explicitly. We could do this on the "API front-end" by building a set of high-level utilities that would embed the GraphQL queries, but that would essentially double much of the work being done in the front-end (and more than double if some customers want to use Python scripting while others want JS and others want TCL or Perl).

So, we decided that the best place to expose those high-level abstractions is exactly the REST API, where it is maximally re-usable.

Re: Best practices for REST API design (2020)

#182

Earlier quoted context omitted.

What would you do if someone wanted: - some fields of the resource - some fields of the comments - some fields of the user that made the comments

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.

Re: Best practices for REST API design (2020)

#183
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.

> 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.

Re: Best practices for REST API design (2020)

#185
post #138

Earlier quoted context omitted.

If items get returned twice while iterating, then I know something got added. Manga websites do this and it's a nice unintended feature. Slicing by ID is how Github does commit history and it drives me nuts that I can't jump several pages, for example, to see when the first commit was, or to guess whereabouts some commit is given a known time range. IDs make it impossible to do anything but iterate step by step. I mu…

> If items get returned twice while iterating, then I know something got added. Fair point. I agree, that's a nice side effect. But what if you're looking at page 1, and an item is removed from that page? Then you'll never see the first item at page 2, because it's now the last on page 1. > Then if I want a slice from 300-8000th items, I can type exactly that in the URL. That's a nice feature. But it can put a lot of…

> That's a nice feature. But it can put a lot of load on your backend if you paginate over 10 of thousands of items.

To prevent that, usually maximum page size is enforced on the server anyway and the client is informed about the actual page size in the metadata in the reply.

Re: Best practices for REST API design (2020)

#186

Earlier quoted context omitted.

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.

> 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.

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...

Re: Best practices for REST API design (2020)

#187

Design is hard. In the given example we work with an Article domain. Where there are Comments. Fine and totally fair. But how would you design your object graph from the bottom up? Articles and Comments is a fairly simple example. Imagine a Transaction in bank domain context. Would you have an endpoint like so? transactions/:id/acoount/:id Or perhaps transactions/:id account/:id/transactions Whatever you pick you mus…

Sure, but this is unavoidable complexity for any API designer, whether it's REST or C or SQL. Of course you need to think about how to model the business domain and what entities you will expose, and the relations between them.

Re: Best practices for REST API design (2020)

#188

Earlier quoted context omitted.

We could use a name for "standard JSON-over-HTTP stuff that's implemented in a variety of frameworks and libraries". So what shall we call REST without HATEOAS[1]? "RESTless"? [1] https://en.wikipedia.org/wiki/HATEOAS

No, a truly RESTless API must do away with all the other pointless HTTPisms in REST. If you're using any other method than GET or POST, or any other codes than 400 and 200, you're not truly RESTless.

Most of the times I end up with put endpoints with verbs, because that often how businesses work. Objects and processes. Behind a REST resource there is a database table most in of the cases. But what if I want to send an email? POST /emails ? That's RESTless as well!

Re: Best practices for REST API design (2020)

#189

Earlier quoted context omitted.

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.

> 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.

I don't care if you like it or not, if your numbers are actually that large, serialize it to a string and back out on your backend. You shouldn't be blindly dumping json to a structure anyways.

Either that or use a different serialization method to communicate.

No one else seems to be complaining about this issue. If JSON doesn't fit your needs, use something else.

Re: Best practices for REST API design (2020)

#190
post #27

Earlier quoted context omitted.

From a client application perspective, would you want to handle the cases differently?

Of course, hitting a path without a handler is a bug, a resource which doesn't exist is a normal thing.

The situation you describe is not really REST. In REST, URLs are opaque; they have no structure for clients to understand. So, clients don't make up new URLs in order to determine whether resources exist. They only use URLs that they've already been given. If they haven't received it, they don't care whether it exists. This is called "Hypermedia as the Engine of Application State".
Post reply on HN