Live data from Hacker News

Best Practices for Designing a Pragmatic RESTful API

vinaysahni.com

21–30 of 38 posts

Re: Best Practices for Designing a Pragmatic RESTful API

#21
post #12

Some questions that aren't answered in the article: How do you structure batch operations like creating multiple things? Is the current answer to make N queries and hope you're using http/2? Whats the best practice for media types in a json api? Should every object type have a specific media type or maybe just a normal and error wrapper type? Seems like most of the big tech apis don't actually get more specific than…

> How do you structure batch operations like creating multiple things? Is the current answer to make N queries and hope you're using http/2?

OP here. Two approaches:

1. Have a special endpoint (POST /batch) where you send an array or requests [ {method: "", path: "", body: ""} ] and get an array of responses

2. Yes, assume HTTP/2

Based on conversations with teams who've based their API designs on this post, I've previously recommended #1. But it has it's flaws - a request that's dependent on response from another can't be part of the same batch.

Today, I'd say it makes sense to make sure you implement your API with HTTP/2 and reduce per-hit rate limit "costs" for clients connecting with HTTP/2. This way, you're encouraging HTTP/2 adopting for heavy API users.

Note, if you need to batch only on GET, then something like GraphQL is also interesting.

Re: Best Practices for Designing a Pragmatic RESTful API

#22
This has nothing to do with REST (I realize it says RESTful but I wish that term would die as RESTful has nothing to do with REST either). It seems to re-invent OData as well.

I don’t know how it has gone so wrong with REST as it seems pretty easy to understand: it’s how your browser has always worked. Your browser doesn’t know any URLs at all (yes I know about the search engines but that’s configuration). What it knows are data types. It can be taught new data types (e.g. PDF) but not new URLs because it doesn’t know any. So if you want a REST API you need to be designing data contracts between client and server. URLs are a server side implementation detail and completely irrelevant to the discussion.

The advantage to this kind of architecture is that the server and clients can develop in a more more decoupled manner. They need only agree on data types. A new web site existing never requires rebuilding a browser. Only if a new kind of data (e.g. HTML5) is to be supported.

But one thing to be considered, as with all architectural patterns, is if it fits the domain you’re architecting. REST isn’t optimal for any possible problem. Sometimes HTTP-RPC (what the article describes) is an easier fit. But once you realize and accept this you no longer have to follow standards that seem not to make sense for what you’re doing (e.g. HATEOAS which is done automatically if you’re really doing REST, and seems so inefficient if you’re not).

Re: Best Practices for Designing a Pragmatic RESTful API

#23
post #2

If you're interested in API design the upcoming RFC standard might be of interest: https://tools.ietf.org/html/draft-ietf-httpbis-bcp56bis-06

Your link is a bit stale. Here's a link to the latest version of the draft, published October 31st 2019:

https://tools.ietf.org/html/draft-ietf-httpbis-bcp56bis-09

Re: Best Practices for Designing a Pragmatic RESTful API

#25
post #10

An API that uses the Link header can return a set of ready-made links so the API consumer doesn't have to construct links themselves. This is especially important when pagination is cursor based. In the header is nice because then there’s no need to parse the payload to get the next page. But better still is to avoid cursor based pagination. Instead give me a cheap endpoint to get the total number of results and the…

That's indeed the nicer way of paginating, but it breaks if the underlying resultset changes between requests. Which is exactly when cursor based pagination is generally used.

If the changes in the resultset are additive it's no problem as long as they are sorted in such a way as new results go to the end (which the api should at least make an option if possible). Updates to data within results may be a problem because you can end up with a dataset that has a view of the world that doesn't represent any particular time, but in many cases are safe. Deletions screw everything up and should be avoided if possible.

The general solution to this problem is to allow as part of the query some particular time that you want the results to reflect the state of the world as of, but that's obviously going to be expensive to serve.

Re: Best Practices for Designing a Pragmatic RESTful API

#26

An API that uses the Link header can return a set of ready-made links so the API consumer doesn't have to construct links themselves. This is especially important when pagination is cursor based. In the header is nice because then there’s no need to parse the payload to get the next page. But better still is to avoid cursor based pagination. Instead give me a cheap endpoint to get the total number of results and the…

+1 to what your other response said

You have to remember the goal of pagination: to move through a collection of results sequentially. If your underlying page is constantly changing (as the other response noted), then you have NO way to know what should be your next intended offset/page to move either or back.

A simple sort with "results always go here" seems like a good approach but now you're packing additional understanding into using your API which is totally out of band with it. Or using a different sort blows it up rending that approach useless.

Cursors are the only approach that actually accomplishes the goal.

Re: Best Practices for Designing a Pragmatic RESTful API

#27

An API that uses the Link header can return a set of ready-made links so the API consumer doesn't have to construct links themselves. This is especially important when pagination is cursor based. In the header is nice because then there’s no need to parse the payload to get the next page. But better still is to avoid cursor based pagination. Instead give me a cheap endpoint to get the total number of results and the…

+1 to what your other response said You have to remember the goal of pagination: to move through a collection of results sequentially. If your underlying page is constantly changing (as the other response noted), then you have NO way to know what should be your next intended offset/page to move either or back. A simple sort with "results always go here" seems like a good approach but now you're packing additional und…

If the underlying data is constantly changing, how do cursors solve that problem? The only guarantee I get asking for the next page after a given item is that it won't contain the last item I've already seen. There's no other inherent guarantees. The page could contain all items I've already seen, early pages (in this new version of the underlying dataset) could have items I've never seen, and so on. It's as arbitrary as page numbers but without the corresponding convenience.

Re: Best Practices for Designing a Pragmatic RESTful API

#28
post #4

> Should the media type change based on Accept headers or based on the URL? To ensure browser explorability, it should be in the URL. The most sensible option here would be to append a .json or .xml extension to the endpoint URL. I disagree with this. The most elegant solution is to use Accept headers, and you should therefore implement that. Of course, since those are hard to use from a browser, you should also solv…

I don't agree that there should be browser explorability. I don't understand why that would even be a concern. When I explore it's from documentation, postman or curl. The browser is kind of horrible for this why support it at all?

Re: Best Practices for Designing a Pragmatic RESTful API

#29
post #12

Some questions that aren't answered in the article: How do you structure batch operations like creating multiple things? Is the current answer to make N queries and hope you're using http/2? Whats the best practice for media types in a json api? Should every object type have a specific media type or maybe just a normal and error wrapper type? Seems like most of the big tech apis don't actually get more specific than…

> How do you structure batch operations like creating multiple things? Is the current answer to make N queries and hope you're using http/2? OP here. Two approaches: 1. Have a special endpoint (POST /batch) where you send an array or requests [ {method: "", path: "", body: ""} ] and get an array of responses 2. Yes, assume HTTP/2 Based on conversations with teams who've based their API designs on this post, I've prev…

>Have a special endpoint (POST /batch)

This is what always seems hacky to me. Why don't we start with batch handling. Why shouldn't every (POST /resources) accept an array of new resources? We've already resigned to using plural everywhere.

HTTP/2 would be nice, but as a dev that has to serve Unity client, we can't even design APIs that require PATCH.

Re: Best Practices for Designing a Pragmatic RESTful API

#30

Regarding API versioning, FTA: > There are mixed opinions around whether an API version should be included in the URL or in a header. Academically speaking, it should probably be in a header. However, the version needs to be in the URL to ensure browser explorability of the resources across versions (remember the API requirements specified at the top of this post?). I don't see how this is relevant with a RESTful API…

When you see versioning it's a pretty good hint that they use is as a buzz word and it's just RPC wrapped in REST clothing
Post reply on HN