Thinking in REST
I've been reading blogs around the .NET community lately and there seems to be some serious confusion about what exactly REST is. Is it a SOAP replacement? Is it a definition of how to prepare data for consumption by AJAX clients? And what does it have to do with all this new MVC stuff we've been hearing about? What is it exactly?
In the .NET and Microsoft world - we have been conditioned to believe in SOAP as the way to do machine conversations over the web (although SOAP of course is capable of much more than just web based services). In fact if you ask any .NET engineer what a web service is I'd bet that you'd here him/her talk about SOAP and probably ASMX or WCF as well. It's just as well too because honestly SOAP is a very well defined and robust way to do that job, and because it is so well defined we as .NET engineers often don't even have to think about the details, instead having them be handled automatically for us by the framework and tools we all love so much.
So then why are we even talking about this? Well, it just so happens that the entire world of technology doesn't actually speak SOAP. If you are a Java or .NET engineer you'll have no problem finding tools to parse out the WSDL and spin up clients for you automatically, but if you are using PHP or ActionScript you are likely going to have problems (especially if the service is using SOAP 1.2). But almost all technologies today have do have one thing in common - they can make web requests. Almost every technology has the ability to make POST and GET request, and most of those support the extended set of HTTP verbs as well (HEAD, PUT, DELETE, etc...). The nature of REST is to use those verbs, those verbs that are as old as the HTTP spec itself, to represent actions and to use that information to allow a service to make decisions about how it processes requests.
Now then - let's start thinking in REST.
So what is REST? Perhaps if we expand the acronym that will help us understand it better: REST = Representational State Transfer. Hmmmmm. I don't think that adds any clarity to the situation. So instead let's talk about what really sets it apart from the web services technologies/concepts you are already familiar with. The first think you need to be able to understand that REST is all about resources. "That's nice." you say, "But what exactly do you mean by 'resources'?" Well, resources are the things that make your application what it is. In a blog you have resources; posts, comments, pictures, etc. In an ecommerce site you have resources; products, user reviews, users, orders, and so on. REST is all about thinking of your application in terms of those resources instead of t
hinking about how you will provide interaction to those resources to your clients. Let's look closer at the blog resources I mentioned.
If I wanted to provide a SOAP API to my weblog I'd probably start by writing 2 methods: GetPost and GetRecentPosts right? But wait - I already HAVE a way to tell the server that I want to get a post...
http://mycoolbutfictionalblog.com/posts/my_cool_post
See? If that were a real weblog, I bet I could follow that to a post called "My Cool Post" or something along those lines right? So let's take a look at what the browser is doing when we follow that link.
GET /posts/my_cool_post HTTP/1.1
Host: mycoolbutfictionalblog.com
(more stuff we'll talk about later...)
Look at that! The browser is doing EXACTLY what I want to do with my web service! It's GET-ing the post. But what happens if I want to get a list of all the posts? I guess I would go to:
http://mycoolbutfictionalblog.com/posts
And the browser would do:
GET /posts HTTP/1.1
Host: mycoolbutfictionalblog.com
(more stuff we'll talk about later...)
So all by itself our blog has managed to support 2 methods that I wanted to create in my web service. I already have "GetPost" because of the GET /posts/my_cool_post
and I have "GetPosts" by means of GET /posts
. The only problem of course is that these posts are returning in HTML format right now. Not ideal for using in a web service.
The truth is, at this point, we can truly claim that we have a RESTful web service to retrieve a Post or a collection of Posts. REST doesn't define what format the resource is in - and that is where a lot of the confusion comes in. Until learning about REST, you probably thought about that blog post as a web page that had a blog post on it. Now that you are beginning to understand REST you should see that it is a blog post formatted as a web page. The post is what we are asking for, it just happens that the current delivery of the post is using an HTML container.
Once that logic is in place then, we can see how we could do the exact same thing but instead of formatting the post as an HTML web page, we could choose to format it as XML. We could choose to format it as JSON, or AMF, or any other way we might want to return that resource to the client.
There is quite a bit more to be written on this subject, and I'll pick it up again in a later post. For now though, remember, if you aren't talking about resources - you aren't talking about REST.