Posts Tagged ‘REST

28
Aug
08

What is REST ?

What it is not

Too often I have heard the term REST used in a wrong way. Sometimes people think that when they are accessing a Web Service via a simple HTTP GET and the URL, they are using REST.

For example I’ve seen stuff like this in the Axis2 documentation, where they say, that you invoke a deployed SOAP service the REST way by using your browser and navigating to a certain URL:

http://domain.com/service-name/service-method?parameter=value

This is not RESTful!

So a lot of times you can see services claiming having a REST interface, when in reality they only have a HTTP GET interface, which totally misses the point. (Don’t get me wrong here, Axis2 actually seems to have real REST support, but the above example is not part of that!)

Okay, so what is REST then?

REST uses the HTTP architecture and (usually) XML, which are basically used everywhere. It does not add a new protocol layer (like the SOAP envelope for example) on top of that. Unlike SOAP, you don’t define services with actions (methods) and arguments.

Instead it’s all about resources and representations. All resources can be listed, viewed, created, updated or deleted. And every resource has at least one representation (think of it as rendering the raw data), for example in XML, HTML or Plaintext.

It is best described using an example:

A bookstore example

Say we have a bookstore where we want to publish books and let authors upload their own books.

So what we need to do is create, read, update and delete books. (Note the 4 verbs and the noun books in there) This is basically what all RESTful web services do: basic CRUDing. That’s also what databases do by the way in addition to allowing complex search queries.

The nice thing now is that HTTP already supports keywords for exactly these use cases. I guess you all know GET and POST requests. But there are also some other verbs defined like PUT and DELETE for example.

Listing all items

Listing resources is usually the first step for a user of the REST service to get an overview of what’s available. It is similar to viewing the items, but instead it returns all resources of a certain type. To list all books of our store we simple send a GET request to the following URL:

http://domain.com/books

This will return a list of <book> elements in the HTTP response body, like this:

<books>
  <book>
    <id>1</id>
    <title>Cryptonomicon</title>
    <author>Neal Stephenson</author>
    <price>19.95</price>
  </book>
</books>

Currently there is only one book, let’s upload a new one.

Creating resources

To upload a book, we POST to the very same URL. The nice thing about REST is, that we reuse URLs (resources) all over again, we just change the verb to tell the service what we want to do with it. So just send a POST request to the books resource:

http://domain.com/books

As you can see there are no parameters supplied in the URL, the actual payload is in the HTTP request body, like this:

<book>
  <title>World War Z</title>
  <author>Max Brooks</author>
  <price>14.95</price>
</book>

Note that there’s no id-parameter supplied yet, as this is not needed, because the web service will create one when it actually stores the book in its database backend. (You as the web service author are responsible for doing this, Rails does it automatically)

Now what do we do if we want to update the price of a book? Let’s use 2 steps for that, to see a real world use case, and also learn some theory and vocabulary.

Representations

Your data is usually saved in a (relational) database. But your users need a certain view (a.k.a. representation) of this raw data. And you can represent your data not only as XML, but also as HTML, JSON, CSV or whatever format you need. If you want you can also support multiple formats, and let your users decide which representation of the data they want to see.

For this HTTP has the content-type header, which you would set to application/xml to get your book in XML as we need to do in our examples. (Note: We needed to send this content-type for every request so far, but I haven’t mentioned it yet, to keep it simple at the beginning.)
 

Show me a resource

To get a book with the ID 2, we send a GET request with the content-type header of application/xml to the following URL:

http://domain.com/books/2

Note: We could also identify our books via something more descriptive, e.g. their title, but then we have to make sure that a) each title is unique and b) the id-part of the URL is all lowercase and uses dashes instead of spaces (this is not absolutely needed, but makes the URLs much easier to read – it’s really confusing to use mixed case in URLs for the end user). An example URL for the above book would be:

http://domain.com/books/world-war-z

Modifying the Show view

In any way we get the following XML back, which is basically the same we uploaded before, but with an additional ID field, which was inserted by our backend. (Note: If we would use the title as our ID, then obviously this field is not present)

<book>
  <id>2</id>
  <title>World War Z</title>
  <author>Max Brooks</author>
  <price>14.95</price>
</book>

So lets say, we want to increase the price of the book, because it’s so good. We just set the text of the <price> element (with our XML library of choice or a simple String-replace) to our new value.

Updating a resource

Now that we have the updated XML representation of the book, we are ready to upload it to the server. REST uses the HTTP method PUT for updating.

Just send a PUT request (with the XML payload in the http-body) to the URL of this resource:

http://domain.com/books/2

If everything went well, the server should send a HTTP status code of 200 (OK) or 201 (Created). The nice thing is that HTTP already defines all the status codes you need, so no need to reinvent the wheel. And you can always send additional status messages in the body of the response.

Delete with DELETE

So you think this was easy? (I hope so) Then wait till you see how we remove resources. There is a HTTP method for exactly this use case, which was not really used before REST. Just send a DELETE request to the target resource:

http://domain.com/books/2

There you have it, same URL again, different method.

Summary

That is the basic architecture of a REST based web service. Basically you send one of the four HTTP request methods to a URL and put any payload directly in the HTTP body. The server sends a response with an appropriate HTTP status code and also puts any content in the body.

Advanced uses

Let’s say you also want to view certain chapters of a book. Usually you would think of something like this:

http://domain.com/books/2?chapter=1

This is also the way Axis2 handles arguments to a service’s method. But doesn’t it look way better the following way:

http://domain.com/books/2/chapters/1

This is the concept of nested resources. You have a full URL (without any URL parameters) that identifies a given resource. It gets even clearer when you have an even deeper nesting than two. Let’s say we also want to view certain pages of a chapter. Compare the following:

http://domain.com/books/2?chapter=1&page=2

This doesn’t make clear if we mean the 2nd page of the book or the 2nd page of a chapter. With nested resources it’s unambiguous:

http://domain.com/books/2/chapters/1/pages/2

It should be clear, that this returns the 2nd page of the 1st chapter of the 2nd book. Note that we always used the plural version of a resource. This allows us to GET a list of all chapters using the URL:

http://domain.com/books/2/chapters

And it also allows us to POST new chapters to the very same URL!

Advantages of the REST approach

First of all I think it’s really simple (you need to have a basic understanding of HTTP though – which every web developer should have anyways). And you are reusing existing technology, instead of adding even more to the already crowded IT world. For example you can use HTTPS in combination with HTTP basic authentication for security.

Because SOAs often forward messages and act as middleware, you can make use of the lightweight HTTP redirection and referrer mechanisms.

All REST services have a uniform interface. Unlike SOAP you don’t really need a WSDL to see what methods are available for your service: if you know which resources are available, you know that you can GET, POST, PUT or DELETE them.

REST services can be invoked by the browser. When you have HTML representations, you can GET them with the browser, and you can also POST resources (e.g. as JSON). Unfortunately current browsers do not support PUT and DELETE requests from HTML forms (maybe Firefox3 does, not sure?), but I’m sure we will see these in the future.

Disadvantages

As REST uses the CRUD approach, it is sometimes not easy to implement certain service designs. For example a calculator in SOAP style would have add() and multiply() methods with 2 (or more) arguments.

In REST you have to rely on the GET, POST, PUT and DELETE methods, so at first this problem might seem untackable. But with a different way of thinking, it could be realized like this: You have sum and product resource, which you will GET for different arguments, for example:

http://domain.com/calculator/sum/1/2

Which simply return 3 in the body. You could always use dynamic number of arguments like the following:

http://domain.com/calculator/product/1/2/3/4

And this would return 24 and a status code of 200 (ok).

Additional Reading

There’s a lot more to REST than I could cover in one mere article (for example caching). Whole books can be written about RESTful design (somehow I know only one). To get started here are some links I found helpful:

Advertisements



October 2017
M T W T F S S
« Jan    
 1
2345678
9101112131415
16171819202122
23242526272829
3031