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/…
If it's an API then you could bypass the aforementioned constraints of spitting your request up by URI "directories" and instead have your query's parameters passed via form data or serialised as JSON* in the HTTP request body. URIs are easier to deal with but not _that_ much easier if you're programmatically sending the requests as one might expect to do with an API * Other data formats also exist
Rules for REST API URI Design
71–80 of 97 posts
Re: Rules for REST API URI Design
#72Earlier quoted context omitted.
We've already established REST has crippling limitations. No, we haven't. I explicitly disagreed with that assertion. REST is not adequate for everything, but it doesn't have "crippling limitations". It's pretty good for its intended use. You can also make it a long lived connection, that waits for a proper confirmation, which means you might be waiting ten seconds. You can't rely on the connection lasting that long.…
... Then make an endpoint where you can get a task's status through its ID (your post to sendmail would then return a task ID), and poll repeatedly until it's marked as done, wasting bandwidth, your architecture, your choices ¯\_(ツ)_/¯ Or you can let the server notify you when it's done, and carry on with your work. As a bonus, most clients able to receive SSE already include automatic reconnection to the feed if it…
This is how WebSub (formely PubSubHubbub) works on top of RSS/Atom, for example.
Re: Rules for REST API URI Design
#73URI normalization takes care of trailing slashes (RFC3986). If you are parsing URLs yourself try to stick to the WHATWG URL standard ( https://url.spec.whatwg.org/ ).
I hadn't seen this before - it's horrifying. Right up the top it declares that its intent is to _obsolete_ the existing RFCs - and then just breezily drops this in: "As the editors learn more about the subject matter the goals might increase in scope somewhat." Honestly, I'm gobsmacked. I really hope nobody's taking this document seriously.
Their concept is also not to standardize new stuff, but to always only describe what the largest browsers (often simply Chrome) do.
Re: Rules for REST API URI Design
#74Nice rules, except for #7. Class names are singular, as are most SQL tables in modern SQL. I think this pattern should be followed also in URL design, since it’s more common to refer to a single at /person/327 than the list of all people at /person. However, everyone designing an API should be aware that the REST principles really don’t work very well without HATEOAS, and HATEOAS does not require any “designed” URLs,…
The client (if it's not a human) can't magically discover the semantics, and a HATEOAS API can't properly describe the semantics - it will give you a relationship type string that might be descriptive of what the URL will do, and that's it.
In any case, you need to define a mapping between "I want to do X" and an item on the server side; and when writing a client there's not much practical difference (only a conceptual one) between linking "do X" to an URL string versus linking "do X" to a HATEOAS relationship string. You gain some stability if the service renames some methods, but unless you're really sure that it was just a cosmetic change and none of the semantics has changed, you need to re-verify everything anyway if it happens.
Re: Rules for REST API URI Design
#75Earlier 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.…
So you'd want the server to send all the formats it can provide (i.e. as a list of different resource URLs) and the client chooses whatever it prefers, entirely the other way around as you describe.
Furthermore, server being able to dynamically respond "I don't do your preferred format" is not a desirable outcome; from the client perspective you'd want to know if the format is available right away, and for a whole class of URLs, not an individual URL at the very last moment. I.e., I'd want it to be equivalent to a "compile time check", that an URL scheme promises that the server will always be able to return type X for such URLs, instead of a "runtime check" where the availability of a particular format is known only after you try it.
Re: Rules for REST API URI Design
#76Two points that I don't understand. 1. Using dash instead of underscore as a space replacement. Underscore is a much more natural as a space replacement and dash is actually a punctuation character. An article gives the following reason: "Text viewer applications (browsers, editors, etc.) often underline URIs to provide a visual cue that they are clickable. Depending on the application’s font, the underscore (_) char…
The argument with the most weight right now is probably that everyone uses dashes and there are no significant advantages to using underscores. So, to help the web a little more consistent, just use dashes (unless you have some unusually good reason not to).
Re: Rules for REST API URI Design
#77Two points that I don't understand. 1. Using dash instead of underscore as a space replacement. Underscore is a much more natural as a space replacement and dash is actually a punctuation character. An article gives the following reason: "Text viewer applications (browsers, editors, etc.) often underline URIs to provide a visual cue that they are clickable. Depending on the application’s font, the underscore (_) char…
Regarding your point in 2: do you store your docs in a directory called Documents or Document?
When you name the resource you are naming a directory/table. You pick a file/row in it by either using an ID or query parameters. That's how you reduce the many to the one.
Just like how you say "one of the students" (singular lookup, /students/42) or "students who study CS" (plural query, /students?studies=cs). Not "one of the student" (singular, looks ok: /student/42) or "student studying CS" (plural, but reads as singular: /student?studies=cs).
Re: Rules for REST API URI Design
#78Earlier 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.…
The general route for a resource is an endpoint that can serve both application/json and application/xml, the ".json" route identifies an endpoint that will serve only application/json and ".xml" identifies an endpoint that will serve application/xml.
None of that conflicts with normal content negotiation, and normal conflict resolution is used. So if the client were to send a request to a .json endpoint with Accept: application/xml it would get a 406 response.
The problem it solves is to make it straight forward to send ad hoc API requests from a browser but still control the format. The browsers I work with don't generally make it easy to specify an accept header. This is useful for demos, issue investigations, and ad hoc testing.
Re: Rules for REST API URI Design
#79Re: Rules for REST API URI Design
#80I would disagree on the artificial file endings. It's a very transparent way to allow the client to request a resource with a specific content type, visible right there in the URI. After all the .json and .xml are unique representations of the same resource and can reasonably have their own URI
The thing is that resource should have ideally one URI and selecting representation should be done through content negotiation (e.g. Accept header). Of course having an option to use file extensions makes debugging easier in a browser.
You start off with a statement of ideals which you then directly contradict with a real, practical concern.
I think that has to mean the ideal isn't a good one and in fact -- here's the interesting part, IMO -- one or more of the considerations on which the ideal was based are also invalid.
Personally, I think the "lesson" here is that we should not aspire to have a one-to-one relationship between URI and resource. The attraction is that it's simple. But I think it's clearly too simple; that is, it is too inflexible to be useful: resources cannot be transferred between hosts or shared by multiple hosts; resources can only be organized in a single fixed way (for all time!) within a service (itself with a fixed organization within its host).
It seems better not to try to impose these restrictions on resource identity and instead separate how a resource is identified from how it is retrieved. E.g. use a UUID to unambiguously identify a resource across all space and time, but retrieve the resource using a set of URLs which can change over time. I mean, the idea that a resource can move (its URL has changed) has been is built into HTTP for decades. Why attempt to create a service that assumes this does not happen?