The document discusses several API anti-patterns including overuse of GET and POST methods, tunneling errors through responses, lack of proper response codes, absence of caching headers, hypermedia as the engine of application state (HATEOAS), versioning issues, and lack of content negotiation support. It provides examples of bad and good practices and concludes with reminding API designers to leverage standards to avoid confusing or annoying API consumers.
63. GET: /droid/r2d2
GET: /droid/c3po
404: Not the droids you’re
looking for
64. HTTP/1.1 200 OK
Content-Type: text/plain
<?xml version="1.0" encoding="UTF-8" ?>
<response code="error">
<error>Error!</error>
<text>You have errored.</text>
ed t o do
</response> I su ppos
What am this?
with
110. Thanks!
Mike
Pearce
mike@mikepearce.net
mikepearce.net
twtitter.com/mikepearce
Editor's Notes
Welcome to PHPLondon August 2010 meetup.
I&#x2019;m here to talk about API Antipatterns and, more specifically, the use of REST.
or, some great ways to piss off your customers and users.
or, I&#x2019;m going to teach you to suck eggs.
or, we&#x2019;ll just laugh at other peoples&#x2019; expense.
So, hello, thanks for coming, you&#x2019;re all wonderful, really.
My name is Mike Pearce, this is my avatar, you&#x2019;ll see it liberally splashed about on various social networks.
You can usually find me as &#x2018;MikePearce&#x2019; on most networks.
or &#x2018;MikeyPearce&#x2019;
or even mikepearce.net
but, mostly MikePearce. I work for Affiliate Window, although I&#x2019;ve only been there two days, so don&#x2019;t ask me anything about them. Anyway, my contact details will be at the end if you&#x2019;re still awake, or even still here...
Firstly an apology. this presentation is ill written, probably badly researched and definately un-rehearsed. I only had a couple of weeks notice and most of that time was already taken up with things like working, eating sleeping and high-maintenance children.
I also went to a festival, Sonisphere at Knebworth
I ate too much
Drank too much
and everything I had ever learned about my job fell out of my head for four days. Monday arrived, then Tuesday and I still hadn&#x2019;t done it.
So, along with starting a new job, I&#x2019;ve spent the last 48hours glued to Keynote.
Anyway, I shall get on with it now.
You probably think I am here to talk about REST, right?
Well, I&#x2019;m not.
Actually, I am ... sort of. I&#x2019;m here to talk about how NOT to do rest, which is much easier!
The do&#x2019;s, the dont&#x2019;s and the whatevs of a REST API.
Roy Fielding is a 45 year old Californian who ...
Is one of the principle authors of the HTTP 1.1 RFC
He also wrote a dissertation in 2000 called &#x2018;Architectural Styles andthe Design of Network-based Software Architectures&#x2019; for a doctorate of philosophy. Hands up who has read this!
... and chapter 5 had all the meaty stuff about REST.
Rest isn&#x2019;t HTTP ...
and REST isn&#x2019;t &#x2018;The Web&#x2019;. I&#x2019;ve heard REST summarised as Roy Fielding&#x2019;s way of describing the existing architecture of the web. While this is true, that&#x2019;s not all it is. REST principles can be applied with many other technologies.
REST isn&#x2019;t particularly hard to get right.
REST isn&#x2019;t particularly hard to get right.
REST isn&#x2019;t particularly hard to get right.
REST isn&#x2019;t particularly hard to get right.
There aren&#x2019;t really any standards.
Just a few constraints and a couple of guidelines.
http://www.flickr.com/photos/joe_13/19946186/ joe_13
REST is really a set of verbs
which are applied to nouns.
Here is a short example...
JON, can you
me a pint
So, let&#x2019;s get into the anti patterns.
So, the first antipattern and these aren&#x2019;t in any particular order is..
http://www.flickr.com/photos/23846880@N00/391925649/ Rutger de Moddertukker
Probably one of the most obvious, yet most abused pattern is to use GET or POST for everything. As I mentioned earlier, REST is about applying verbs to nouns. The nouns HTTP has are few, granted, but still distinct enough to each have their own jobs.
CAN YOU NAME ALL THE HTTP NOUNS?
TRACE - Echoes back the received request, so that a client can see what (if any) changes or additions have been made by intermediate servers.
OPTIONS - Returns the HTTP methods that the server supports for specified URL. CONNECT - Converts the request connection to a transparent TCP/IP tunnel, usually to facilitate SSL-encrypted communication (HTTPS) through an unencrypted HTTP proxy
PATCH - Is used to apply partial modifications to a resource.[8]
An example of GET tunnelling. While this is clear enough what&#x2019;s it&#x2019;s doing, it&#x2019;s not adhering to a rest restraint, so, not really RESTful.
Good example of storing a document
PUT or POST is a question you&#x2019;ll often ask yourself and it&#x2019;s not always clear cut. Generally, you&#x2019;ll use a PUT when you saving a document at a certain location or in a collection
and POST when you want the application to decide where to save the document.
It&#x2019;s not clear cut though, so use your best judgements. Just remember that when you PUT a document at a location that it already exists at, you should PUT the entire original document, otherwise you should use UPDATE.
Here is an example of using POST to delete.
This is much better, it&#x2019;s semantically correct and shorter to boot!
Next up, tunnelling all errors through 200 OK. This is one of my biggest beefs and something that&#x2019;s caught me out as a consumer a couple of times now.
Anyone recognise this?
When consuming the API of my wife, I ask her, &#x2018;Are you OK?&#x2019; and she response with &#x2018;Fine&#x201D; which, in my head, is a 200 ok.
http://www.flickr.com/photos/yourdon/2573762303/ - Ed Yourdon
Or this?
From my wifes point of view.
The error I&#x2019;m receiveing reflects the request I made. It&#x2019;s not 200 OK not the droids you&#x2019;re looking for. THAT would be confusing.
http://www.flickr.com/photos/thunderchild5/225675773/
THIS is the most confusing and downright useless response I ever received from a Telco provider I worked with in my last job. A 200 OK code, with a plain text header and an XML body...
Which leads on nicely to response codes. There are many Response Codes that you can return which will provide the consumer with a much better idea of how to handle the body of the response. They fall broadly into five categories.
1** information codes eg: continue, switching protocols
2xx codes: 200 OK, 201 created, 202 accepted
3xx redirection: 303 moved, 304 not modified
http://www.flickr.com/photos/duchamp/126115989/ - Duchamp
4xx codes: 404, 401 Unauthorised
http://www.flickr.com/photos/thefangmonster/490423135/ - The fang monster
5xx codes. Really, the crux of the matter here is use response codes that are relevant to the response you are sending.
A 200 OK is an appropriate response for a successful PUT request, but to really be on the ball...
... send a 201 created!
You can also make up your own codes, if the standard ones really don&#x2019;t cut it.
You can also make up your own codes.
One of the greatest benefits of using HTTP is caching. However, HTTP caching is complex and scary. You should use it where you can and encourage your clients to make use of ...
ETags are sent with the header and are a unique representation of that resource at that time. Collision-resistant has functions should be used to generate an etag, which is sent to the client. the client stores caches the etag along with the rest of the response, but the next time it makes a request to the URI, it sends an if-none-match header, which contains the original etag. The server will compare the two and, if nothing has changed, send a 304 (Can anyone tell me what a 304 is?) (Not Modified), otherwise, it will respond with the new data.
More about caching is outside of the scope of this prez, talk to me afterwards if you want to know more (although, I don't know much more!).
Cookies, delicious right?
http://www.flickr.com/photos/projector/2092517108/
By allie pasquier
Don't do it. If you have to, don't put server state data in them and don't authenticate with them. I have no idea yet how local storage will affect how I develop an API.
http://www.flickr.com/photos/nickstone333/3135320160/ nickstone333
What is hypermedia?
What is hypermedia?
Hypermedia is the sequel to Hypertext. Hypermedia includes audio, images, text and links.
http://www.crystalxp.net/galerie/en.id.3751-bagg-a-png.htm
HATEOAS: You should be able to access your API from a single URI and be able to traverse the entire API by just knowing the one URI. If you forget this, you're not taking advantage of one of the core concepts of REST. Your API is now self-documenting and can never be out of date. For example, what a consumer does:&#xA0;
GET: /users/MikePearce
(assuming it's not cached) the API should return user information about me, but also information about how to modify me, how to delete me and links to other collections that have something to do with me. It should really also return a number of fixed URIs for adding collections.
Or should it?
That's one way of doing it, another way would be to publish one URI which lists all the features of the API and the URIs that you can access them with. Perhaps the endpoint as a start?
Most clients will construct their own URIs, but mostly because they're never given any links to follow from the API in the first place! You can change this!
So, as always there are grey areas. The lack of any standards or an RFC for REST means that there's often areas of the discipline which, for some, offer the opportunity for wiggle room. The first of these, which you will see debated frequently (and there's some great discussions on Stack Overflow) is...
http://www.flickr.com/photos/rdrcollection/116454033/ Rodney Ramsey
As with anything SAAS, your API will change over time and this means that some of your URIs may change. Now, the URI is the most prominent part of a RESTful API. It is something the users will use forever. It is a long term commitment to the user, so you have to get it right first time. However, there might be times when you absolutely have to change the way something works. For example, your initial design decision to make the URIs human readable means you might end up with a request like this:
But, you've now decided that you'd be better off requesting the user from their ID.
While less human readable, the margin for error is less. However, now all your consumers and clients are unable to query for both. You could program your API to look for strings AS WELL as integers, but it's going to get messy quickly. So, the best bet is to version. I'll explain a couple of methods for versioning, but you should decide what is best for you.
3. No versioning at all (but with a 'sunset' period) (This is more difficult if the clients consuming your API are paying for it, or don't move very quickly, hence this becomes business decision, not a technical one.
Another grey area, but this one only really has two choices. How does your client request particular document type?
http://www.flickr.com/photos/turatti/4526352835/ jaci xIII
You either use the .extension style...
or send Accept headers with your request. You should bare in mind though that some servers WILL cache old accept headers or, in some instances, completely ignore your Accept headers. So it&#x2019;s probably safer to use .extensions
Summary.
Don&#x2019;t use get and post for everything. There ARE other verbs to apply to your nouns.
Use appropriate error codes. If it&#x2019;s an error, it&#x2019;s not 200 OK (unless you were expecting and error code and 200 OK IS an error...)
Use appropriate response codes. A 201 created or 202 accepted is preferable to a 200 OK after a mutation.
Be responsible with caching. Suppy clients with an expiry time for the data you suppy and also encourage them to use etags
Only use cookies if you really have to and make sure they contain stateless data. Prefer HTTP Auth over cookie auth if you can.
Hate Oars, or, remember to provide links to other relevant parts of the API with your response. You can also provide a directory of URIs at your end point if you like.
Versioning is totally up to you, there are a few options, it depends on you and your clients&#x2019; needs.
Use &#x201C;dot&#x201D; extensions or an Accept header, perhaps even both for those proxies which don&#x2019;t behave themselves.
Which leads on nicely to response codes. There are many Response Codes that you can return which will provide the consumer with a much better idea of how to handle the body of the response. They fall broadly into five categories.
My name is Mike Pearce, this is my avatar, you&#x2019;ll see it liberally splashed about on various social networks.