Live data from Hacker News

Best Practices for Designing a Pragmatic RESTful API

vinaysahni.com

11–20 of 38 posts

Re: Best Practices for Designing a Pragmatic RESTful API

#11
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…

Using Accept headers is the right thing, for the reasons you specify, and also the additional reason that they allow for the client to specify a list of possibilities that can be negotiated down to a result (server doesn't understand `application/vnd.hal+json`? maybe it can still send you `application/json`).

That said: the extension-implies-media-type approach may not be right for an application server that renders a resource on the fly, but it does seem to have a place in the specific kind filetree-via-http web server, where the resource specified by a given URL is already rendered to a specific media type, and the server really only has two choices for figuring out what that type is: parse the file (potentially expensive) or apply a heuristic set up in the server configuration to the filename (potentially not specific enough or outright wrong). Neither choice is necessarily wrong for that subcase.

I'm iffier on saying as much for media-type-in-query-string method. It's easy enough to use a client built for sending headers like Postman or curl or to augment common browsers with extensions that using the understood HTTP convention seems like the right thing for most cases. The only exceptions I can think of would be those where debugging a media type specific issue needs to happen on machines devs don't control. Needing to debug issues on machines devs don't control is common enough, but issues specific to rendering one media type should be rarer, and the intersection of both of them should be vanishing unless something isn't right elsewhere in the dev process.

Re: Best Practices for Designing a Pragmatic RESTful API

#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 'application/json'.

Re: Best Practices for Designing a Pragmatic RESTful API

#13
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…

Using Accept headers is the right thing, for the reasons you specify, and also the additional reason that they allow for the client to specify a list of possibilities that can be negotiated down to a result (server doesn't understand `application/vnd.hal+json`? maybe it can still send you `application/json`). That said: the extension-implies-media-type approach may not be right for an application server that renders…

Also, rest is interesting because it solves a lot of "base protocol" questions. Accept header is part of standard http.

So that should be the default way.

Re: Best Practices for Designing a Pragmatic RESTful API

#14
Great sunday reading. However, in the section "But how do you deal with relations?" the author presents nested resources as a best practice. I don't feel this is the best course of action. Instead of nesting message resources in, say, `/tickets/12/messages/5` shouldn't a better approach be to store them in `/messages/5` and keep `/tickets/12/messages` as a collection of IDs or summary resources? I mean, messages are a separate entity which might even be moved to a dedicated microservice. Why is it a good practice to nest them within an API?

Re: Best Practices for Designing a Pragmatic RESTful API

#15

Great sunday reading. However, in the section "But how do you deal with relations?" the author presents nested resources as a best practice. I don't feel this is the best course of action. Instead of nesting message resources in, say, `/tickets/12/messages/5` shouldn't a better approach be to store them in `/messages/5` and keep `/tickets/12/messages` as a collection of IDs or summary resources? I mean, messages are…

"might even be moved to a dedicated microservice"

Allowing for scenarios like that would actually be an argument for HATEOS (where, at least in theory, URLs are treated as opaque).

NB I have tried designing using HATEOS and I'm not a huge fan - but it would help in this case.

Re: Best Practices for Designing a Pragmatic RESTful API

#16

Great sunday reading. However, in the section "But how do you deal with relations?" the author presents nested resources as a best practice. I don't feel this is the best course of action. Instead of nesting message resources in, say, `/tickets/12/messages/5` shouldn't a better approach be to store them in `/messages/5` and keep `/tickets/12/messages` as a collection of IDs or summary resources? I mean, messages are…

there's a trade-off involved in latency size and server hits

shipping name and description of some resources often read together allows to minimize cost and optimize performances, up to a point

ultimately the client knows what the UX needs and it's in the optimal position to ask for the minimal resources needed, hence graphql et al.

but that leaves the rest API designer in a rut, where to make the call for nesting and where for searching related?

if I had to draw the line, if the related entity has a non null foreign key (or the nearest applicative equivalent) toward the parent it's a prime candidate for nesting

Re: Best Practices for Designing a Pragmatic RESTful API

#17
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…

> Should every object type have a specific media type

Probably not. Consider that a given object in a system might have a json representation, an xml representation, an html representation, etc. Media types are less about the in-system representation or type for a given entity, and more about how the entity is rendered. Many different in-system entities might be represented by the same media type, a single in-system entity might be rendered as several media types.

(In practice, yeah, application/json will cover you, though application/vnd.api.vN+json gives you some room to maneuver negotiate version/app specifics with various clients using Accepts headers.)

Re: Best Practices for Designing a Pragmatic RESTful API

#18

Great sunday reading. However, in the section "But how do you deal with relations?" the author presents nested resources as a best practice. I don't feel this is the best course of action. Instead of nesting message resources in, say, `/tickets/12/messages/5` shouldn't a better approach be to store them in `/messages/5` and keep `/tickets/12/messages` as a collection of IDs or summary resources? I mean, messages are…

there's a trade-off involved in latency size and server hits shipping name and description of some resources often read together allows to minimize cost and optimize performances, up to a point ultimately the client knows what the UX needs and it's in the optimal position to ask for the minimal resources needed, hence graphql et al. but that leaves the rest API designer in a rut, where to make the call for nesting an…

> there's a trade-off involved in latency size and server hits

I might have not conveyed the point adequately, but my point was orthogonal to networking or HTTP calls. I was referring to how resources were being needlessly nested, thus leaking direct dependencies wrt other resources. More specifically, although tickets might refer to messages, I didn't understood why nesting messages within a ticket passed off as a best practice. I mean, if ticket already provide a collection resource of message resource IDs, why is the path to message resources being defined specifically with regards to specific tickets?

Re: Best Practices for Designing a Pragmatic RESTful API

#19

Earlier quoted context omitted.

there's a trade-off involved in latency size and server hits shipping name and description of some resources often read together allows to minimize cost and optimize performances, up to a point ultimately the client knows what the UX needs and it's in the optimal position to ask for the minimal resources needed, hence graphql et al. but that leaves the rest API designer in a rut, where to make the call for nesting an…

> there's a trade-off involved in latency size and server hits I might have not conveyed the point adequately, but my point was orthogonal to networking or HTTP calls. I was referring to how resources were being needlessly nested, thus leaking direct dependencies wrt other resources. More specifically, although tickets might refer to messages, I didn't understood why nesting messages within a ticket passed off as a b…

I think there’s some confusion on what the original problem is: how do you get the ticket, together with its messages, in the minimum number of api calls ? That’s why parent post mentions latency and graphql.

The other problem : « having already queried the ticket, how do i get its messages », does indeed allow for various answers : tickets/Id/messages , or /messages?ticketid=xx or even /messages?ids=a,b,c,d are valid, depending on how orthogonal tickets and messages are, and don’t depend on latency, indeed.

Re: Best Practices for Designing a Pragmatic RESTful API

#20
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. In REST, resources are transparent and found through HATEOS/autodiscovery. Thus it's really irrelevant if the URL found through HATEOS includes an API version or not.

However, URL versioning is a indeed a side effect of having multiple services dedicated to serve each version of an API.

In the end, it doesn't feel like path/media type versioning is a relevant issue because it's not an either/or type situation but actually complementary.

Post reply on HN