RESTful Applications

Most people are familiar with how to create a RESTful application, or at least a RESTlike application using their preferred language. In most languages there are even frameworks that allow for easily creating a RESTful application [1]. You can see this post as the personal ramblings of an interested person or just as some personal notes on how to REST.

Think Resources, not URLs

A resource can be seen as any individual type of data, using the example of a blog you could consider a post, or a group of posts as a resource. Say you want to get a list of blog posts, you might expect this to exist at this resource:

http://host/blog/posts

Or if you wanted to get a particular post you might go for:

http://host/blog/posts/RESTful-Applications

Know your verbs

The HTTP protocol makes use of methods to describe the action performed on a resource, these are often referred to as HTTP verbs. Common verbs that are used in most RESTful applications are

GET – Get the content of a resource

POST – Create a new resource

PUT / PATCH – Update an already existing resource

DELETE – Delete a resource that already exists

  • I want to create a new blog post so I would use the POST method against the http://host/blog/posts resource.
  • If I wanted to view the post I had just created I would use GET against the resource http://host/blog/posts/RESTful-Applications.
  • Then, I decide to update a part of the post, I would use a PATCH or PUT against http://host/blog/posts/RESTful-Applications.
  • Finally I scrap the entire blog post by sending a DELETE to the same resource http://host/blog/posts/RESTful-Applications.

If you think about each action and the verb / resource pair that goes with it, you might notice that the first request went to the resource http://host/blog/posts, this is because you are adding a new post to the list of blog posts. Whereas when we go to delete the post we are specifically deleting the resource http://host/blog/posts/RESTful-Application.

There are a lot more verbs available in the HTTP protocol, OPTIONS and HEAD amongst others you can view on the W3C website and a nice little collection on Anne van Kesteren’s site.

Use curl

Curl is a great tool for debugging and generally exploring HTTP based APIs, in fact I would go so far as saying that any API produced should be structured in such a way that any developer unfamiliar with the project should be able to explore the API using curl and nothing else. There are a few arguments you might find useful when testing an API with curl.

Decide what to output to the terminal

If you want both response headers and response body:

curl http://host/blog/posts -i

If you want just the response headers:

curl http://host/blog/posts -I

If you want just the body:

curl http://host/blog/posts

Send some headers

You can define request headers using the -H option, some common headers include:

“Content-Type” – The mime-type used in the request body

“Accept” – Content-Type that is acceptable for the response body

If we wanted to specify in our request that we expect the api to pass back a response in JSON format we would run this curl command

curl http://host/blog/posts -H "Accept: application/json"

Most commonly used headers can be found here, though it is worth noting that you can use any HTTP headers in your API, even ones you make up [3].

Use different HTTP methods

You can send a request using any method you like using curl, here we create a new category for blog posts.

curl http://host/blog/categories -X POST -H "Content-Type: application/json" -d '{"name":"New Category Name"}'

HTTP Headers

Headers are used by the HTTP protocol to define anything you want about a request or response. This can be the date, the HTTP response code, or anything you like that could be specific to your application or the infrastructure it is running on.

Content-Type and Accept Headers

In some APIs you might see a requested as follows:

curl http://host/blog/posts.json -i

or

curl http://host/blog/posts.xml -i

This just feels like all sorts of wrong, these URLs are specifying two distinctly separate resources and not two different formats for returning the same resource. A RESTful API should respond to any request using the content type specified in the Accept HTTP header of the request. Commonly this would be JSON or XML, specified by application/json and application/xml respectively. [2]

So instead of what we have above, the following should be used:

curl http://host/blog/posts -i -H "Accept: application/json"

or

curl http://host/blog/posts -i -H "Accept: application/xml"

Acquaint yourself with Mime Types

Mime types are a description of how a particular piece of content is formatted. Your browser can accept lots of different formats of data but usually it is only useful if the data it receives is in HTML format, which has a mime type of text/html. If you are sending data to an application using jQuery’s $.ajax method this would usually be done using JSON, with a mime type of application/json.

There are a stupendous number of mime types and an incomplete list can be found on the Sitepoint website here.

Request Body

Just like the response from a web server contains a body (the HTML that your browser renders), any request made to a web server can contain a body. When making a request you can put whatever you want in the body, although it is best to use a recognised format, like JSON or XML, and declare the type of data being sent using a “Content-Type” header and a mime type.

Resource Query Strings

Many people will be familiar with url query strings, an example might be http://host/resource?query=something, you might think this a grave mistake what with all that I have been going on with, but no. Query strings can be used when you want to limit the information an api call returns.

Say you have a resource that returns blog posts, well if you have more than 10 blog posts this might get a little unwieldy. One solution is to allow your api to return 10 posts at a time with additional pages of results obtained by using the ?page query string.

Pollers

When polling, if the information you are obtaining is large (maybe a large dataset or similar), poll with a head request. Your API should be able to give the latest update timestamp for any information being requested, and the requesting application should then be able to make a GET request for that updated information if it needs it.

I will more than likely add to this post over time, however I reckon that these observations should be good for the moment. As always, please feel free to comment.

[1] Implementing Rest – Frameworks

[2] Implementing Rest – FAQ

[3] Node HTTP Module – Message Headers

This post has been viewed 8410 times.

Leave a Reply

Your email address will not be published. Required fields are marked *