REST worst practices
jacobian.org
jacobian.org
That was in a comment by Alex Payne [1] near the bottom. Obviously it's been quite a few years since he wrote that but it's what I personally think, too. The extent that many blog articles and comments take REST really adds far too much complication. Are client-side developers going to understand how to use your API? Always keep your target market in mind.
Honestly in my mind that's the most important point to take from this article.
Putting the format in the URL itself is much easier than having to fiddle with HTTP headers. Not to mention the ability to view API data directly within the browser is a major advantage in discoverability.
When I am trying to connect 2 systems I prefer to think about functions rather than resources , basically create "namespaces" and have something like: www.myapp.com/api/namespace/function then simply pass all data in using POST vars and serialize anything more complicated into JSON then just have to other end return JSON or XML.
Sometimes I will implement a simple header system with some metadata that should be sent and received with each request.
Getting too worried about POST/GET/PUT seems silly when you can just give your functions appropriate names.
I prefer to think of this as SOAP extra light.
If you do give it a read, you'll find that his paper isn't about "shoehorning into HTTP". Actually, the title is pretty clear: _Architectural Styles and the Design of Network-based Software Architectures_. After doing a great job of classifying different types of problems and possible solutions to these problems, Dr. Fielding describes REST as a solution to a particular kind of problem. To quote (from his blog):
> REST is intended for long-lived network-based applications that span multiple organizations. If you don’t see a need for the constraints, then don’t use them.
It's fine if you don't want to use REST, but it's obvious from your comment that you don't understand what REST is or when you might use it.
I apologize if I have mis-represented the arguments for/against REST it's just my experience that a lot of debate around REST seems to be people discussing which resource something should belong to or whether something should be POST or PUT.
These sorts of conversations don't really make your software better (I often feel the same way about OO inheritance).
As Jare mentioned, I don't like the idea of returning url pointers. But, I always run into a wall when it comes to deciding how 'deep' to load certain entities. Does anyone have any interesting approaches to making it dynamic based on the client request? Or should you just expect the client to make additional calls to get more data.
[1] http://www.stereoplex.com/blog/mobile-api-design-thinking-be...
IMHO, we'll end up with something equivalent to relational algebra. It's the same problem: providing different representations of one data model (e.g. how far to expand links is an instance of denormalizing a flat list). But it won't happen til providing different representations becomes critical.
Perhaps it is inevitable that we'll eventually need rich query languages to really deliver what clients want.
Though, queries are distinct from relations. They are a database concept, existing before Codd's relations and also present in NoSQL etc.
I was thinking of the relational concepts that SQL builds on. A way to separate these concepts is to do the query in two stages: (1) a relational transformation over the database that denormalises it (joining lists) into a list containing your answer; (2) a query to extract that answer. (These two stages are usually redundant; it's just a way to think about it, not how to write the query, nor for a DB to implement it.)
In a sense, the nesting of REST APIs means they are heavily de-normalised: to access some data, you have to start at the top and work your way down that "path". They sometimes have multiple paths to the same data, each one representing a different denormalisation. The reason this is not "relational" is because you can only use pre-existing paths; you can't make up your own as needed.
It's only in a narrow sense that REST APIs are normalised, in that you can only return one list, with no joins in it.
Looking at WCF Data Services http://en.wikipedia.org/wiki/WCF_Data_Services, those examples aren't (necessarily) relational, just queries, in that there is no transformation, just selection of a sublist. It's not fair to judge it on one example though. I found another eg http://msdn.microsoft.com/en-us/library/dd728279.aspx it's analogous. Maybe I'll read the specs in detail later. :-)
BTW: A query returns a subset of the database. It seems sensible to return only the subset needed. But there's an odd trade-off in REST: caching more than a specific query needs is more likely to be useful for the next query (in effect, it distributes the database over network caches). Bandwidth is plentiful, so let's return 10KB instead of 10 bytes. But latency is a problem (IMHO); presently, we need several requests to get the data we want.
I just had an idea: a rich REST API query language (as you say), and also have a client-side query language, and a client-side optimisation engine that transforms each query into a form that maximises cache hits. e.g. get much more information than needed, if it happens to be cached nearby. It is like the query optimisations that databases presently use, but on the client, on the other side of the expensive network.
You could also over-request, to populate the cache for future queries (your own and from other users). This might need a lot of tuning, based on actual usage patterns between users. Existing web-caching experience might guide this.
Finally: at the moment, I think it's clearly true that different ways of accessing the same data are not that important. Perhaps they'll never be, for web-data that is always used in the same way. The "enterprise" needed relations because they have heaps of apps using centralised data in different ways (manufacturing, inventory, sales, analysis, etc). However, as the enterprise moves into the cloud, and as developers start to construct services out of services (with much deeper integration than a simple mash-up; more like using remote libraries), this will become extremely important to some users.
whoa, long post. just trying to get my thoughts in order. hope it's of some use.
By default, it's reasonable to assume the requester only wants the barest of information (along with links to related resources) when they access /hero/superman.
But it's perfectly reasonable to provide additional views for common use cases e.g. /hero/superman/powers/detailed or /hero/superman/friends/filter/powers/flight.
See http://stackoverflow.com/questions/4024271/rest-api-best-pra...
If you look at the twitter API (https://dev.twitter.com/docs/api) (commonly held up as exemplary REST) you will see exactly 2 methods, GET and POST. GET means no state change other than logging, POST implies state change. This makes so much more sense because then you can use ?command= and have any command you want and not have people confused about what it means.
calling "PUT a=b&c=d" three times should be identical to calling it once. So any time you let the system generate an ID for the resource you should use POST.
PUT works in creation when you know the id beforehand.
I have not worked with amazon s3 but I hear they handle this well. You PUT a file to a url containing the file name. The first PUT creates the file on their end, any future PUT updates that file.
PUT specifies the resource to be update, whilst POST does not do so. This means that you must (according to RFC 2616) use POST if you want to create a new resource and PUT if you want to change an existing resource or create one that you know "how to name". This disctinction is sometimes necessary, or at least useful (ex: idempotence of PUT).
I don't understand how any even half-competent developer would be unable to understand this difference and act accordingly.
My point is not that the ascribed meaning of POST and PUT is bad, I think the concepts behind both these functions are great, but what if you want to make a different or more complicated function? It makes sense to me to invent your own rather than be limited to what HTTP gives you.
This isn't complicated stuff.
Not by people who know what they're talking about.
> This makes so much more sense because then you can use ?command= and have any command you want and not have people confused about what it means.
That's textbook RPC. It's a pattern that works well for many things, but it's definitely not REST.
One of his goals was that a document would be able to provide links to another document in a natural, intuitive way. It is ment to be so intuitive in fact that the interchange of the document doesn't need a schema or WSDL like system. HTML has this ability. JSON however doesn't.
If one wants to nest links in JSON, one has to tell the client how those links will appear. On has to define the structure beyond merely syntaxical correctness. This is where REST falls down, IMHO.
So I recommend pursuing pieces of REST. But a full HATEOS concept seems to meaningfully limit on to symantec HTML.
Then use HTML. Or some other representation with known link semantics.
I don't see how failures or shortcomings of JSON indicate a problem with REST. They are orthogonal; JSON has nothing to do with REST, it's just a serialization format some people like.
The long and the short of the document was that a REST client must be able to navigate the entire API when given just a single endpoint URL, much like you can navigate an entire website just by entering the homepage URL into your browser, but without the dependance on HTML.
The leap the document made, and what virmundi seems to be referring to, is that a REST client that speaks, say, JSON is not enough to traverse any random service, as everyone will provide a completely different JSON representation of their data. When you start hardcoding site-specific keys in which to find the action descriptions, you lose all of the flexibility the author claimed REST would provide in the first place.
I've downloaded the original thesis. I'll look there to see what's mentioned about the hypermedia linking process.
Or define link semantics in JSON, the one documentation a restful service should have is that of media types (the documents returned) anyway, the only URL which should appear in the documentation is the root of the service.
Whining that JSON has no link semantics is nonsensical, SGML does not have any either, HTML added those when it was first created as an application of SGML, just as text/xhtml+xml is an application of XML defining links, "XML" as a meta-type does not know about links either.
No he's not, he's baked hyperlinks into his thesis as the base of REST, that has nothing to do with HTML.
> One of his goals was that a document would be able to provide links to another document in a natural, intuitive way.
No. His goal is merely that documents be hyperlinked, how is the application's domain.
> It is ment to be so intuitive in fact that the interchange of the document doesn't need a schema or WSDL like system.
I don't know where you got that one, but it's definitely not part of Fielding's thesis or his comments on the subject since. It's in fact exactly the opposite, the one thing Fielding notes must be documented in details in a RESTful service is media types, aka the documents returned by the service. That's where hyperlink semantics are added.
> JSON however doesn't.
Neither does SGML or XML, that's not an issue.
> If one wants to nest links in JSON, one has to tell the client how those links will appear.
Just as one has done with HTML.
> On has to define the structure beyond merely syntaxical correctness.
Just as with HTML.
> This is where REST falls down, IMHO.
That's complete and utter nonsense.
The only difference between HTML and JSON is that HTML is already an application of a meta-document type (well used to be, of SGML, it's drifted further but conceptually it still is) whereas JSON, much like XML, is a meta-document type from which users build applications (what do you think application/xhtml+xml is?).
You sound like you want some magical silver-bullet through which you don't have to document anything and things suddenly understand each others based on fairy dust. Reality does not work that way.
This shouldn't matter much, but it does.
[0]http://goo.gl/UFSdZ (links to Chrome extension store)
I had to build an API that lived inside a system with entirely too many authentication/cookie checks and using curl was becoming too awkward for testing, this saved me a lot of time.
If I could break it down to the simplest form:
GET requests can be cached, any other method should be processed.
My personal best practice would be to build batching facilities for your APIs. Batching is incredibly important when your application data grows.
Can you explain a bit more? I'm just surprised because returning URLs (not IDs) is a fundamental idea of proper REST.
In particular, my doubts about IDs vs URLs is the ability to store those pieces of data in the client (or intermediate caches) - if the service URLs or namespaces change, the client-side URLs become useless even after the client updates the service entry point. With IDs, that information would still be usable.
I'm absolutely no expert on this so I'm probably in the "HTTP API, not REST API" side of the problem.
Same concept as deprecating code. You don't wipe it out straight away because you have no idea what else might rely on it or how fast they are to react (within reason).
As for the arguments about not using HTTP request methods - they're standard, and are implemented uniformly everywhere (for the best part). Your API isn't standard, but if all APIs use HTTP and its request methods correctly, you only need to learn the general HTTP spec to generally understand all APIs.
Resources and URL structure afterwards is a matter of opinion. What may seem RESTful to me might not be to someone else.
One other semantic nitpick is that a URL is a subset of URI, which stands for Universal Resource Identifier, so in some sense you could make a philosophical argument that URI and IDs are/should be the same thing. If you were really crazy you could store URLs in your DB (obviously not a good idea for many other reasons).
Which is OK, because the client can re-traverse the service to get back to those resources which are now invalid.
I've not thought much about this but Roy Fielding disagrees [1].
[1] http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...
Aside what appared to be a fundamental misunderstanding on the GP's part, there is the legitimate concern that an individual resource shouldn't need to know its own URL. In the article, that was just glossed over, though.
One could, for example, have a book by ID 1 trickle the ID up the application call path, and at a higher level, a complete URL is generated. In fact, the application could simply be a module inside yet another one that wants to add its own ‘namespace’.
What the URL is and how it's generated doesn't matter. All that does is that the URL is made available (discoverable), and that it goes to the right resource, however that happens.
Let's say we have an "Event" Resource and it belongs to a "Location" Resource and the Event belongs to "Category" Resources. If you want to provide an endpoint to search events with a GET requests and filter based on Location and Categories (which are identified by URLs) you can end up with really long query strings.
/events?location=URL1&categories[]=URL2&categories[]=URL3&categories[]=URL4&...
This is not only ugly, it can bring up problems on both clients and servers.
Any suggestions on how to handle this?
The point is that REST uses Hypertext as the Engine of Application State. You might have heard of this as HATEOAS.
Ideally, your API is discoverable given the initial URL. If you return IDs, I have to construct URLs based on information I already have. If you return URLs, I just have to make an HTTP request.
Basically, I can't understand why anything he writes is somehow hackernews worthy...is he self-promoting?
So you have no idea who he is, apparently did not look for any information (such as his gh page or his being one of Django's lead devs) and decided he was all about "political skills". And somehow failed to realized the article linked above is 3 years old.
> Basically, I can't understand why anything he writes is somehow hackernews worthy...
But that does not prevent you from judging him as "a politician who can't write code". Nice.
> is he self-promoting?
He "self-promotes" 3 years old articles by not even posting them himself? What sense does that make?
Here's an idea: maybe he wrote good content, and he's not too bad a writer. But you know, if you want to insult him you could at least do it to his face, he's a member on HN after all: http://news.ycombinator.com/user?id=jacobian
Maybe he is the ultimate "trick baby"....or is Django something we cannot question on hacker news. I think this dude is full of shit myself.
Instead of insulting people, try to learn to properly discuss ideas. Learn to point out failed reasoning and to defend your own concepts with sound reasoning or facts. Once you start, it's not that hard and it makes the discussion so much more useful. We have limited time. We shouldn't waste it.