Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
On RESTful API Standards – Just Be Cool: 11 Rules for Practical API Development (appnexus.com)
72 points by jedwards_tech on May 1, 2012 | hide | past | favorite | 34 comments


I don't think adding metadata to your responses goes against the ideas of HATEOAS. On the contrary, HATEOAS requires enough metadata about the application state and possible transitions so that a consumer can fully interact with the API without relying on out-of-band information (URL patterns being the most common example).


Some people argue that whatever you get back from the request should be the exact json/xml/whatever object representation.


Can you point me to a source for this argument? I'd be interested in taking a look at the reasoning behind it. Obviously, that's an approach that a lot of people take for pragmatic reasons, but it doesn't seem to allow the kind of hyperlinking that's the core idea of HATEOAS. Of course, the term "object representation" is pretty generic, and may obviously somehow include links to related resources and application states.


I doubt Fielding would agree:

"The model application is therefore an engine that moves from one state to the next by examining and choosing from among the alternative state transitions in the current set of representations."

http://weblogs.java.net/blog/mkarg/archive/2010/02/14/what-h...


Yes, pretty much this is how I've been doing JSON API's for a couple years now. Making things all about convenience and ease of use for the API consumer, that's really what an API should be about. Afterall, API's are UI for developers.


Generalizations are bad. At work, although our front end uses our REST API, it is also used by many different backends of clients that integrate with our service.


All generalizations are bad.


Yes! Thank you.


Developers that view "Practical API Development" as something more important than agreed-upon standards is also the reason Microsoft Internet Explorer has a long history of suck.

"But honestly, why would your users be creating an object with an id?" They aren't. You should not be PUTting endpoints with an id. I get more more and more scared as I type, thinking about this change-the-standard-for-my-own-purpose attitude.


I'd appreciate other people's input on these choices. I'm currently implementing an API much in the way of these standards, but I'm almost buckling and implementing PATCH since I feel dirty having PUT do so much, so incorrectly.


You have to analyze your target audience. Will people who are new to using a restful api being using your api? Will you provide a wrapper yourself?

There are about a million questions you must ask yourself in order to come to the right answer for YOU. At the end of the day what matters is that the person using your API finds it easy and intuitive. If that means that you use PUT for updates, and POST for creation, so be it. It could even mean that you convert PUT to POST requests, and treat them all the same. If you take that route, you check to see if the resource ID is specified in the post data. If the ID is in there, you update that resource, if it's not in there you create a new resource.

While you go forward, keep in mind one thing. If your API is hard to use then no one will use it. If no one uses it, then your API doesn't matter. If your API doesn't matter, then you made all the wrong decisions.

Also, have fun with it. Creating APIs is incredibly fun, enjoy yourself, and enjoy creating something people will enjoy using.


One thing to keep in mind about wrappers is that now a days kids like accessing APIs from mobile applications. With iOS you cannot simply just wrap curl calls like you would in PHP. Developers use weird and random REST API accessing frameworks in iOS.


I would be interested in finding out more about these REST API accessing frameworks in iOS. Do you have any links?


Just off the top of my head I know of https://github.com/AFNetworking/AFNetworking, http://allseeing-i.com/ASIHTTPRequest/ (no longer supported but still used), and http://restkit.org/


Is it feasible to create subresources for each partial put? For instance, if the `/person/:id` resource has an address as part of the data, could you do PUT `/person/:id/address` to only overwrite the address?


ARGH! PATCH is for partial updates, not PUT!


Does this really rise to the level of an "ARGH!"? I mean, look: REST is nice because it simplifies front end network APIs that were getting out of hand. That is its value.

Replacing the nonsense of SOAP and XML-RPC with equally ridiculous pedantry about HTTP minutiae is not helping your cause nor your software.


There are all of nine HTTP methods, using them correctly should not be that difficult.

edit: Well, ajross has a point. There are actually all of eight HTTP 1.1 methods, and PATCH is not one of them.


The cargo-cult fallacy that there is a "correct" way to do something as complicated and varied as web service provision is exactly the kind of nonsense I'm talking about.

It is "easy" to blindly follow any rule. In most cases it is also wrong.


There is a good reason to adhere to common usage for the common verbs, though: you can meet expectations better. We generally know what to expect out of GET because it's used consistently.


I'm talking about the correct way to use a HTTP method as defined by the HTTP specification.

> It is "easy" to blindly follow any rule. In most cases it is also wrong.

Come on.


Then you are speaking from ignorance. PATCH is not part of the HTTP specification. It's defined in an IETF RFC (5789) upon which the ink is not yet dry (March 2010, and in fact it's not even stable: the most recent errata was 31 days ago).

Feeling entitled to making firm pronouncements about "correct" behavior on subjects one is not an expert in (and let's be clear: no one is an expert on PATCH yet) is in some sense the very definition of "cargo cult mentality".

Edit: that's probably harsher than it's intended. My point isn't really about PATCH, which seems sane. It's about the pedantic mentality which is running rampant in the REST community (c.f. the "ARGH!" above), which in my mind is taking a good idea and polluting it with terrible nonsense in the pursuit of "purity". Think of what happened to Agile if you continue down this path.


Well shit, my mistake.


Great edit. I was starting to wonder what all the opposition to PATCH was about.


Also how do you make a PUT or PATCH request from programming languages like Actionscript (and quite possibly Javascript though I'm not sure) which only support POST and GET requests currently?


Many frameworks overload the POST operation and allow the desired verb to be specified in the data.

Rack::MethodOverride does this for Rack-based apps by using the value of the _method parameter as the http verb.


FYI Javascript supports PUT. I suppose firewalls could be a problem...


As someone else said, the API is the UI for the developer. It should be as intuitive and straight forward as possible. I would expect PUT to replace a resource at a specific URL and POST to create a resource under a URL. Therefore, to do a partial update, we need a new verb.

Having said that, I like subresource URLs and using PUT to do partial updates like that.


Why? What's the actual problem with using PUT for idempotent partial updates?


Consistency. You're entitled to break verb conventions, but you may confuse newcomers or force API consumers to special-case for you.


As a server receiving a PUT request that does not contain all of the fields on your resource, your options for handling the response are:

1. 400 bad data - a failed request

2. Blank out / delete the values of all fields not specified

3. Perform a PATCH-style partial update

Which of these is the most useful / least surprising / closest to the spec?

Now read the spec: http://tools.ietf.org/html/rfc2616#section-9.6 PUT should store the request as the resource, it doesn't have to. Also note the complete absence of push from the precious specification! (I know patch is an amendment, my point us that the HTTP spec shouldn't be considered perfect)


If my PUT passes validation, I'd expect the resource to be overwritten with my request body (#2). If it doesn't, 400 (#1). If I do a PATCH, I'd expect #3.

If PUT falls back to PATCH, then there's no replace action, which might be useful.

It doesn't end up being a huge deal practically, because partial updates are probably more common than replaces, but that's my reasoning for it.



In a lot of APIs I've dealt with, you can create resources with ids that match your own resources, hence wanting to use PUT for creation, e.g. if you have users in your application and you want to extend them to this web service, instead of having to store an additional "foreign key" per user, you can just PUT users in the web service with ids from your own service.

I'm doing this for the API I'm building, as modeled on FatSecret's API.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: