Live data from Hacker News

Rules for REST API URI Design

blog.restcase.com

31–40 of 97 posts

Re: Rules for REST API URI Design

#31

Earlier quoted context omitted.

The last case sounds like user error to me. You could say the same for using Accept headers - what happens if the user tells their line-drawing client to request a spreadsheet?

In the case of accept headers, you would have actual negotiation; the client sends all of the formats it accepts, and the server chooses the most suitable one. If none are available, it would return a 406 Not Acceptable. The problem with putting another , incompatible serialisation format on top of that is that it creates conflicts, and inherently requires one to reinvent the wheel, or have a less flexible solution.…

That's a fair response, but you're presupposing a client that behaves as it's supposed to.

To my mind, the problem it solves is familiarity - average users are accustomed to "file.html", not "file(oh hey, send the text/html version please)".

All of this is heavily influenced by who your users actually are, of course.

Re: Rules for REST API URI Design

#32
post #21
post #20

Earlier quoted context omitted.

just drop this REST hype altogether and use adequate protocols for communication

As in design a custom TCP/IP protocol for every application?

As in using GraphQL for this purpose, I presume. Or even offering an SQL-API. Seems more ideal than overly complicated URL schemes.

Re: Rules for REST API URI Design

#33
post #21

Earlier quoted context omitted.

As in design a custom TCP/IP protocol for every application?

I think there are a few GraphQL enthusiasts entering this thread right now, which has its own merits, but can live perfectly next to REST.

In my company we use graphql for getting, and REST for all other operations.

Might be an antipattern, but has served us well.

We're also using a special flavor of graphql that returns the data as flat dictionaries instead of deeply nested dictionaries. Whether you need that or not of course depends on the client design.

Re: Rules for REST API URI Design

#34
post #19

When doing something like `student/1245/courses` there will certainly be a scenario where you want a list of courses on their own as well. If planning ahead, does that warrant designing your route such as: `/courses` where you get a list of courses and `/courses?studentId=12345` Where you get courses scoped to a student... Or is it better to just recreate a separate route such that you have /courses AND student/2345/…

I just had this exact 'problem' with an API I'm building. I just ended up creating both routes which accessed the same internal function to return the same results - no duplication of code necessary. Personally I think this is a good resolve as it answers both use cases depending on the accesssors context.

Re: Rules for REST API URI Design

#35

Overall this seems like a clickbaity list of practices that have been well established for a while now. REST is easy when you're just doing CRUD. It's once you have actions besides "update" that things start to get a bit more interesting.

I disagree, it's fairly simple, people only find it hard because they're thinking in RPC terms - in commands instead of resources.

An action is simply a new resource you create. You don't send_emails(), you create a new email sending resource, which has its own URL you can check in later (giving you built-in resilience to network cuts and other problems).

I'm yet to find an action you can't easily model with resources and their representations.

Re: Rules for REST API URI Design

#36

Orthogonal: I wish there was a good RPC protocol for the web. REST really sucks when you're not doing CRUD (which, frankly, is way more often than expected).

There's nothing problematic about non-CRUD in REST, it's just a matter of not thinking in RPC terms.

Re: Rules for REST API URI Design

#37
post #19

When doing something like `student/1245/courses` there will certainly be a scenario where you want a list of courses on their own as well. If planning ahead, does that warrant designing your route such as: `/courses` where you get a list of courses and `/courses?studentId=12345` Where you get courses scoped to a student... Or is it better to just recreate a separate route such that you have /courses AND student/2345/…

I just had this exact 'problem' with an API I'm building. I just ended up creating both routes which accessed the same internal function to return the same results - no duplication of code necessary. Personally I think this is a good resolve as it answers both use cases depending on the accesssors context.

To add, my endpoints were:

/accounts/{id}/users

And

/users/account/{id}

Both return the users attached to a particular account.

Re: Rules for REST API URI Design

#38

Overall this seems like a clickbaity list of practices that have been well established for a while now. REST is easy when you're just doing CRUD. It's once you have actions besides "update" that things start to get a bit more interesting.

I disagree, it's fairly simple, people only find it hard because they're thinking in RPC terms - in commands instead of resources. An action is simply a new resource you create. You don't send_emails(), you create a new email sending resource, which has its own URL you can check in later (giving you built-in resilience to network cuts and other problems). I'm yet to find an action you can't easily model with resource…

Could you maybe elaborate a bit more with your send email example? We've been struggling a bit with API design and exactly this kind of thinking everything as a resource. I'm still having a hard time to imagine exactly how "a new email sending resource" would/should look like. having something like /api/sendmail/confirmation would trigger my confirmation mail sending method internally, which clearly is RPC thinking. How would that look like with REST? How would the REST version deal with /api/sendmail/{confirmation,thanks,resetpw} etc.?

Re: Rules for REST API URI Design

#39
post #27

Or, you know, just use GraphQL as your protocol and be done with this. Everything that's problematic in REST is clearly specified here and stays very easy to use. You can focus on real problems from now on.

I think the problem goes deeper then REST & GraphQL, it boils down all the way to SQL and not a lot of people are seeing the problem because it is a "boiling frog" problem. Let me explain. So only a decade ago, all of the work was being done on the server and everything was great (... in a way :), and that's because there you had SQL and you could ask quite complicated questions with it. Now along comes XMLHttpRequest and the iPhone and a lot of the "business logic" starts moving to the frontend slowly. It was a natural thing to do when you need just a little info from the server, basically make "GET /items/1" mean "SELECT * FROM items WHERE id=1", because if you strip all the auth stuff away, that is the essence of that URL. So REST is born. It worked for a while, while the frontend code wasn't doing a lot. But now, we are in a state where everything is being done by the fronted. Now remember all those complicated questions we had to ask of our data, they did not go away, but one thing did, SQL, and all that remained was REST. REST maps to a very limited subset of SQL power, basically all it can do (and still be RESTful) is generate queries like this "SELECT * FROM items WHERE cond1, cond2 ...". Devs were used to working mostly only with queries like this (and ignore joins) because the db was close and there was no (big) penalty for firing 100 queries like these, but now when things moved to the frontend, people started remembering they need to take network latency into account and suddenly "getting everything in one go" ... which is basically a join, became important again. This is what sparked the GraphQL popularity, getting everything in one step, aka ability to express a join everything else is not that important (standard/tooling/types is of course important but it could have been invented for REST also).

Having said all that, GraphQL is still far from the expressivity of SQL and people will still wonder how can they express in GraphQL questions that are easily answered by SQL. Everybody is still thinking in terms of "defining an api" but recently a new way of thinking about this problem started to emerge. Defining a way to translate a HTTP request to a SQL query, i.e. trying to expose the power of SQL in a safe way to the frontend. There is no predefined list of endpoints/types, every requests gets transformed to a SQL query and executed. This is what PostgREST [1] is doing. I know it sounds scary and dangerous but it works :) Try the Starter Kit [2] to get a taste and if GraphQL is your thing, you could explore the same idea using subZero [3]

[1] https://github.com/begriffs/postgrest

[2] https://github.com/subzerocloud/subzero-starter-kit

[3] https://subzero.cloud

Edit: typos

Re: Rules for REST API URI Design

#40
I don't disagree with most of the rules, but it's more than a little ironic that the supporting quote at the top of the page that the article seemingly hangs off directly contradicts most of the article:

> The only thing you can use an identifier for is to refer to an object. When you are not dereferencing, you should not look at the contents of the URI string to gain other information.

- Tim Berners-Lee

By this quote, caring about the hierarchical nature of URIs, pluralization, and enhancements to readability are somewhere between irrelevant to actively harmful (since they promote the idea that the URI contains information beyond identification)

By the logic that a URI is supposed to be used for identification and identification alone, these two URLs are identical in terms of value:

http://api.example.com/louvre/leonardo-da-vinci/mona-lisa

http://api.example.com/68dd0-a9d3-11e0-9f1c-0800200c9a66

Post reply on HN