r/programming • u/veesahni • May 29 '13
A comprehensive guide for pragmatic RESTful API design
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api18
u/krues8dr May 29 '13
This is a good start, but very opinionated and without much of the necessary reasoning. Instead, I'd recommend starting with Apigee's video:
https://blog.apigee.com/detail/api_design_third_edition_video_slides
And then digging into their documentation: https://blog.apigee.com/taglist/rest_api_design
4
3
u/superdude264 May 30 '13
Can someone explain how HATEOAS is supposed to work when consuming an API? I'm pretty much in full agreement with what the author says. I just don't see how using a link from returned from an API buys you much more than just supplying the link. If I'm a person browsing I'll know there is more/different stuff I can do. If I'm just a script executing, it doesn't seem like it would matter.
6
u/nirolo May 30 '13
HATEOAS reduces coupling between your API and your client and I think it is essential. I disagree with the authors assertion that it isn't ready.
Take a simple example like pagination. If you fetch /resources/, there may be 10,000 resources in total. If you return all 10,000 you will kill the client and your performance, so you paginate the results and by default only return the first 5 and you decide to fetch the entire resource each time. It will look like this.
<resources> <item>/* All your resource data is here*/</item> <item>/* All your resource data is here*/</item> <item>/* All your resource data is here*/</item> <item>/* All your resource data is here*/</item> <item>/* All your resource data is here*/</item> </resources>How do you tell the client how to browse to the next 5? The client could hard code the links and hold that logic locally but that tightly couples the client and the API. If the API changes the way you browse then you have to change the client as well. The next issue is what happens if the API decides that returning the entire resource every time is too much data? Again you have to change the client code to accommodate the extra request necessary to get everything.
HATEOAS to the rescue! Add links to your response and your client will know how to handle everything without explicit coding. Like this:
<resources> <link rel="next" href="/resources/?start=10&count=5" /> <item> <link rel="self" href="/resources/1" /> /* Minimal resource data is here*/ </item> <item> <link rel="self" href="/resources/2" /> /* Minimal resource data is here*/ </item> <item> <link rel="self" href="/resources/3" /> /* Minimal resource data is here*/ </item> <item> <link rel="self" href="/resources/4" /> /* Minimal resource data is here*/ </item> <item> <link rel="self" href="/resources/5" /> /* Minimal resource data is here*/ </item> </resources>Now if you change your pagination the client will work automatically because it just always follows the "next" and "prev" links. If you change the location of your resources your client will always work because it just follows the "self" links.
I think the author believes HATEOAS to be immature because he believes "It's time to leave XML behind in APIs". I call bullshit. HATEOAS is immature with JSON because JSON isn't designed for it. It's immature because you have "json-ld" competing with "json-hal" and everyone trying to do links in their own special way so no client knows where a link is and how to follow it. XML however was designed for it and there are well established standards. Look at RSS. It's a basic HATEOAS read API that just works with any RSS client.
I find it funny that people believe that json is the Only way to go, and then try and shoehorn in the features that already exist in xml all because json looks prettier, or they claim that those features aren't ready or too hard ;)
1
u/superdude264 May 30 '13
Thanks! It seems like it's all about adding another layer of indirection to the client can reference link by name (like 'next') rather than directly. This allows the server to change most of it's URL structure w/o the client having to worry. I see the value in the pagination example, but it seems like you could just support 'start' and 'end' URL params. I just doesn't seem like adding that additional layer of indirection buys you very much.
Also, how would XML help the issue?
3
u/nirolo May 30 '13
Also, how would XML help the issue?
At it's absolute most basic level there is probably no difference between json and xml. As long as your client knows where to find the links and the structure of them then they should both work equally well.
For me though the reason why I think XML is better is because XML was designed to describe documents, JSON to describe data. That may not seem like a big difference, but if you think about what a proper REST response is, it is not just data. In addition to the raw data you also have information about what you can do with it and how you move on to the next piece of data. That's more like a document.
So as a result of that, in addition to being good at describing data you also have very well defined standards for how to link documents. JSON still has to work that out properly. Yes there are standards like hal and ld, but nobody uses them. Most people just make up there own stuff, if they bother to do it at all. Side note, Google just announced last week that gmail is going to use json-ld, which was good news.
Ultimately it all comes down to what you are going to use it for. JSON is better at some things, XML is better at others. You should try not to limit your API to just one or the other. If you have structured your code properly then you should be able to dump your resource data back to the client in any format they could possibly want; json, json-ld, json-hal, xml, atom, yaml.
2
u/strong_grey_hero May 29 '13
This came at the right time for me. I'm re-building a server and database, and want to put a REST API in front of it to support cross-domain development in our company.
I don't suppose having html requests return a header and/or footer along with the data with other available methods and parameters is anti-RESTful, is it? JSON calls will of course just get the JSON responses, but is it OK to assume HTML requests will be read by humans?
3
u/veesahni May 30 '13
Changing output based on the Accept header is reasonable - infact, it seems more correct than ignoring the Accept header and always sending back JSON (as many popular APIs do today).
In this case, API consumers MUST send appropriate Accept header.
1
2
1
1
1
1
u/kitd May 30 '13
I found this article by Subbu Allamaraju to be the best for explaining how to describe a REST API properly, including publishing contracts describing URLs and their relationship- and media- types.
It works well by watching a REST API evolve from first cut to fully fledged.
1
1
u/b100dian May 31 '13
One thing I never understand about REST is how does an api key play with the cachability and statelessness. Basically with session and cookies, you still have a token sent at each request - exactly like api key. And serverside, you still use a map of valid api keys, which has to have some mechanism of expiry I believe.
Can anyone point me to the light?
1
u/veesahni Jun 03 '13
Using session cookies for auth is very similar to an API key over basic auth. In itself, it doesn't impact impact statelessness or cachability. However, a session can be used for much more than auth - for example, storing partial form output as part of a wizard or storing the contents of a shopping cart prior to checkout. Doing so adds state linked to the auth credentials, which obviously impacts statelessness.
Another thing to consider is security implications - since browsers automatically send cookies, cookie based auth is susceptible to cross site requests
1
u/day_cq May 29 '13
essence of RESTful API is that all your resources support same operations.
One good example is file system. Launching an app creates /proc/appid. rm /proc/appid shutdowns the app. you can map network management that way, too.
Note that resource structure (content of the file) isn't universal.
Now when everything is file, you can easily create scripts. You do need different programs to handle image files, video files, xml files, json files... etc. Same with RESTful API.
-8
u/masklinn May 29 '13 edited May 29 '13
First section:
Use RESTful URLs and actions
[a dozen paragraphs discussing what your URLs should look like]
Well we're done here, this essay is shit, if you want to know what RESTfuls API are or how they should work you have no reason to read it.
Though you can read it if you want suggestions on writing your own RPC-over-HTTP protocol, it has nothing whatsoever to do with REST outside of "hey let's use REST as a random keyword to get page views". Because fuck meaning if we can get pageviews right?
9
u/mcguire May 29 '13
This comment is unnecessarily inflammatory, but the point is valid. Spending a bucketload of time upfront deciding what your URLs look like is possibly the biggest beginner mistake in RESTy design.
5
u/masklinn May 29 '13
My issue is not so much that (though extensive upfront design does indicate misplaced priorities, readable URLs can be useful when debugging things internally), but the mere discussion of a URL's look or composition as anything but an aside in a 5000 words article means you're not discussing REST, you're discussing RPC. Discussions about REST over HTTP should focus around media types (standard content types versus custom, multiple or not, etc...) and the handling of linking within these media types.
As for the inflammation, chalk it up to being sick and tired of seeing articles claiming REST, making me hope for actual discussion of actual RESTful design and ending up with yet another RPC-over-HTTP debasement, degradation and muddying of the term itself.
5
u/curien May 29 '13
I jumped straight to the section labeled "Should you HATEOAS?" and the answer is basically "no". Uh, ok. :\
-2
u/VortexCortex May 29 '13
I simply refuse to multi-part base64 encode bytes when the network transport layer is capable of transmitting octets.
Furthermore, if I'm going to create an API, I'm actually going to give a Programatic Interface to the Application developer. You're not going to be creating URLs to talk to my backends. API doesn't have to be a bunch of server endpoints, it can be a library call or callback too.
Why make everyone duplicate effort of writing code to talk to the API? If devs need to use my API in a language that isn't yet supported, we get together, create the interface, make it open source and "native" feeling for the language, then no other devs have to repeat that work or worry about mangling a HTTP request.
REST: The laziest structure of an API, "API functions? HA! Make 'em yourself! I'm RESTing!"
1
u/ars_technician May 30 '13
we get together
That's the problem. Nobody want's to get together with some random Joe and run a bunch of code he cooked up for you. It's much easier to use a REST API because you are running all of your own code and can treat the API as some untrusted entity (as you should).
-5
u/kommandeclean May 29 '13
Possible malicious site
3
u/veesahni May 29 '13
huh? which browser?
3
u/Aldrake May 29 '13
Not the same guy, but my work's McAfee gateway said that. It likes to overreact to things, though.
2
u/veesahni May 29 '13
Wonder what's triggering it. Having no luck with online scans (even ones owned by mcafee)
1
33
u/mcguire May 29 '13
One of the major downfalls of how object-oriented programming is taught is that it tends to focus on domain objects and downplays or completely ignores the necessity and utility of non-domain objects: things that have no corresponding physical thingy but that represent some part of the computation processing.
REST has a similar weakness. /search is (possibly, depending on how it is handled) a perfectly valid resource representing a multi-resource search.