Edwin Khodabakchian, once one of the key people behind the Collaxa BPEL product that subsequently found itself part of the core of Oracle's SOA strategy, has been working independently for several years on Feedly which "weaves twitter and Google Reader into a magazine like experience". Recently Edwin posted an experience-based cookbook on best practices for building JSON-based Web Services. No doubt this is a work in progress, but so far the guidelines it provides include:
Phase 1 – Defining a simple resource/service | Take a sample resource such as Customer Information, model it as JSON. Build a simple servlet where PUT creates a new customer, GET returns the customer information based on the customer key, DELETE deletes the customer and POST updates the customer information. Make sure that PUT returns the right information regarding the URL of the newly created resource. In our case, we have a framework which maps JSON to our Java Model and use hibernate to persist that model in a MySQL database. The important things for this phase are to the JSON representation right and the base url formatting simple and clean.
And:
Phase 3 – Adding validation | Change your service implementation to add some data validation to the JSON resource which is being received during PUT and POST. Learn how to use HTTP error code to define and transfer exception information. Learn how to handle those exceptions on the client side. The important thing for this phase is to make sure that you know the existing HTTP error codes, reuse them when it makes sense and create new one which are compliant with HTTP when needed.
At the time of writing there are 7 distinct phases, ranging from the first we've already mentioned, through authentication and to lifecycle. It's always good to see guidelines that are driven by real-world experience and Edwin tries to cover things that have no doubt caused them problems in the past, such as:
There are hundreds of libraries which help you abstract XMLHTTPRequest. Pick one that is cross browser. Pick one that is transparent enough to let you see the GET, POST, PUT and DELETE operations you are calling.
Or:
Defining the right granularity for the business event and the right typing is hard. You might have to iterate a few time to get this right. My advice is to not over engineer it: keep it as simple as possible and re-factor as new use cases appear.
Of course there are references to various aspects of REST that most proponents simply take for granted, such as:
Phase 5 – Adding caching | The web infrastructure offers rich caching mechanisms (last modified information, cache duration, eTag). Learn about those mechanism and see if you can leverage them to improve the performance and scalability of your service
Edwin also covers some highly practical approaches that may at first appear to go against the REST/HTTP rules themselves:
Some servers do not allow DELETE, in that case you need to learn how to do POST with an method overwrite.
According to Edwin they are considering open sourcing some of their back-end infrastructure. Until then documentation for the FriendFeed API is available. With the popularity of JSON+REST on the rise, this is an interesting cookbook for developers to consider and leverage.
Community comments
Thanks
by Edwin Khodabakchian,
Re: Thanks
by Mark Little,
Lack of HATEOAS
by Mike Kelly,
Re: Lack of HATEOAS
by Dan Diephouse,
Re: Lack of HATEOAS
by Manish Bhatt,
Re: Lack of HATEOAS
by Stefan Tilkov,
Re: Lack of HATEOAS
by Mike Kelly,
Re: Lack of HATEOAS
by Dan Diephouse,
Minor remark: POST/PUT semantic
by Thierry Boileau,
Re: Minor remark: POST/PUT semantic
by David Tkaczyk,
Thanks
by Edwin Khodabakchian,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hi Mark. It has been a long time. I hope that you are doing well. Thanks for the post.
Re: Thanks
by Mark Little,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hi Edwin. Great blog entry so thanks for that too :-) Keep 'em coming.
Lack of HATEOAS
by Mike Kelly,
Your message is awaiting moderation. Thank you for participating in the discussion.
As far as I can make out - there is no standard for representing hyperlinks in JSON
This is a significant limitation for JSON as a hypermedia format, for obvious reasons. It certainly not something that cannot be overcome, however.
Maybe the JSON community will make efforts to fix this?
Re: Lack of HATEOAS
by Dan Diephouse,
Your message is awaiting moderation. Thank you for participating in the discussion.
Ummm, isn't it as simple as { "myLink" : "http://foo.com" } ?
Dan Diephouse | mulesource.com
Re: Lack of HATEOAS
by Manish Bhatt,
Your message is awaiting moderation. Thank you for participating in the discussion.
I agree with Dan. I use { "myLink" : "http://foo.com" } for all my JSON representations. So far no issues.
Manish
Re: Lack of HATEOAS
by Stefan Tilkov,
Your message is awaiting moderation. Thank you for participating in the discussion.
Well, one could argue that there's no standardized "<link rel='...' ref='...' />" element in JSON. Then again, there's none in XML either :-)
Re: Lack of HATEOAS
by Mike Kelly,
Your message is awaiting moderation. Thank you for participating in the discussion.
A client would need to evaluate the value of any pair to establish whether or not it was a hyperlink (by checking for 'http://' at the beginning of the value?!) - or it would have to have prior knowledge of the data structure; which would cause some coupling and reduce discoverability.
How would your solution work for relative links?
Here's an alternative..
{ "link": { "$href" : "a/relative/link" } }
Re: Lack of HATEOAS
by Dan Diephouse,
Your message is awaiting moderation. Thank you for participating in the discussion.
You have to have prior knowledge of the datastructure... I hear ya on the whole <link> element thing, but that's one of the tradeoffs of going with JSON. No namespaces. But it's a hell of a lot simpler. Pick your poison!
</link>
Minor remark: POST/PUT semantic
by Thierry Boileau,
Your message is awaiting moderation. Thank you for participating in the discussion.
Hi,
I think that PUT means: "create the targeted resource if it does not exist yet, or update it otherwise".
That is to say: you already know the resource's URI, there is no need to return it.
POST is more generic and can also be used to create another resource having another URI... For example, you can POST "/items" in order to create "/items/123". In this case, that's a good pratice to return the URI of the created resource.
best regards,
Thierry
Re: Minor remark: POST/PUT semantic
by David Tkaczyk,
Your message is awaiting moderation. Thank you for participating in the discussion.
Yes, yes, yes... this is much more correct than what the article proposes!!!