Thursday 2 April 2009
Tesco.com API to become more RESTful
The Tesco API web service endpoint uses SOAP ('Simple Object AccessProtocol') which allows the full service description to be shown to clients in a long and complex XML document. This is no problem if you have Microsoft Visual Studio 2008 since a rather nice 'wizard' takes care of reading this XML configuration and creating lots of client-side code so that your .Net client application can use the web service easily.
However many other Integrated Development Environments do not have this Microsoft-borne luxury, not to mention that fact that some developers like to hand-craft their code directly. To these IDEs and developers, SOAP is a tall cliff to climb to get to configure our service with their client applications. Time and time again I get emails saying "Why can't you implement RESTful services for your API?".
So here I am this morning poring through the book "RESTful .NET" by Jon Flanders (O'Reilly publishing) and I suddenly understand why REST ("REpresentational State Transfer") is so popular: Whereas SOAP performs many actions from one web address (using complex XML documents to describe and access each action), REST's implementation of those same actions uses one-web-address-per-action. REST adopts the true name of a web address - a Uniform Resource Identifier - to describe each action.
Let me show you:
So, our SOAP service endpoint is all at:
http://tesco.cloudapp.net/TescoAPI.svc
...and interacting with all the methods and objects there takes sending and receiving XML documents to/from that service endpoint. Inspecting the web address above gives you no clue as to how to, for example, search for 'chocolate'.
Instead, REST simplifies this by accessing methods through the web address call itself. If I get the RESTful design right, searching for chocolate could be as simple as (contrived):
http://tesco.cloudapp.net/grocery/products/chocolate
To get to my favourite organic cider using its barcode could be:
http://tesco.cloudapp.net/grocery/products/5012845172809
...and anyone can type that manually into a web browser and get the same results as easily as a client application, albeit just data.
What about logging a customer in to get the search from their store? Simple. Just log the customer in using (note the secure 'https'):
https://tesco.cloudapp.net/grocery/login/customer-email&password
...to get a result back containing a unique session ID, e.g. "f7236grrg2g2rg7fg642", and then:
http://tesco.cloudapp.net/grocery/products/chocolate/f7236grrg2g2rg7fg642
Adding to a basket or updating the quantity? Just use the Product ID that is returned with any product search, plus a quantity (here I show a possible alternative, using a query string):
http://tesco.cloudapp.net/grocery/basket/add?id=f7236grrg2g2rg7fg642&productid=347373822&quantity=3
Delete from a basket (again using a query string but alternative syntax is available):
http://tesco.cloudapp.net/grocery/basket/delete?sessionid=f7236grrg2g2rg7fg642&productid=347373822
...and so forth (please remember these are contrived REST actions to show how much easier it is to understand).
Simple, straightforward, understandable - this is what REST offers and the more I read Jon Flanders book the more I have become a fan.
Once I have finished the book I'll go and do some design - but if you are already a seasoned REST developer and there is any direction you think I should go based on your experience I will be happy to listen - just email me at nick 'at' lansley dot com.
9 comments:
As this blog grows in readership - and because it carries the Tesco brand - I have had to become more careful about the sort of comments that are acceptable. The good news is that I'm a champion of free speech so please be as praising or as critical as you wish! The only comments I DON'T allow through are:
1. Comments which criticise an individual other than myself, or are critical of an organisation other than Tesco. This is simply because they cannot defend themselves so is unfair and possibly libellous. Comments about some aspect of Tesco being better/worse than another equivalent organisation are allowed as long as you start by saying "in my personal opinion.." or "I think that...". ... followed by a "...because.." and some reasoned argument.
2. Comments which are totally unrelated to the context of the original article. If I have written about a mobile app and you start complaining about the price of potatoes then your comment isn't going stay for long!
3. Advertising / web links / spam.
4. Insulting / obscene messages.
Ok, rules done - now it's your go:
Great News! Are you looking at ADO.NET Data Services to expose the product catalog or are you going to create a bespoke REST interface?
ReplyDeleteRegards,
Howard
A few links for you:
ReplyDeletehttp://bitworking.org/news/How_to_create_a_REST_Protocol
http://rest.blueoxen.net/cgi-bin/wiki.pl?RestInPlainEnglish
http://hinchcliffe.org/archive/2008/09/08/16676.aspx
May also be of interesting to you
ReplyDeletehttp://codebetter.com/blogs/kyle.baley/archive/2009/04/19/openrasta-or-how-to-speak-rest.aspx
When you create your REST interface, could you also create 'reflection' methods similar to the Flickr API? It's the equivalent of a WSDL file for REST interfaces.
ReplyDeleteCan't wait for this!
Regarding the username and password, you can read the many debates about the Twitter API requiring people to enter their Twitter credentials into random websites... The Tesco API would be so much worse, since we use those credentials to actually buy stuff... I don't want anyone to get that data apart from tesco.com themselves.
ReplyDeleteI'd suggest OAuth is the only want to go with this... The app would then have to send the user to tesco.com to enter their login details and authorise the remote site access to the Tesco API on their behalf.
Hi, does anyone if any of the other major supermarket chains in the UK expose similar info over SOAP/REST?
ReplyDeleteMuch appreciated,
Omer
This comment has been removed by the author.
ReplyDeleteThere's some inacuracies in that post. Wondering if you had more time to investigate ReST more in depth since that post.
ReplyDeleteHi,
ReplyDeleteit's great to see this insight into such a widely used API.
I think you may have fallen short of the REST principles in your example, since I think you're meant to avoid using your own verbs - and rely on PUT,POST,DELETE,GET. So to add to the basket you'd just to a POST to:
http://tesco.cloudapp.net/grocery/basket/id=f7236grrg2g2rg7fg642&productid=347373822&quantity=3
To and to remove something you'd just to a DELETE to http://tesco.cloudapp.net/grocery/basket/sessionid=f7236grrg2g2rg7fg642&productid=347373822
Have a luck at Martin Fowler's review of the REST Maturity Model for more (better) advice on the background to this.
cheers,
Ian