How to design RESTful APIs

Nowadays, you probably heard about RESTful APIs from Twitter, Github and etc. Since REST is a philosophy or design that doesn’t have a concrete specification, there are many blog posts, articles covering how to design RESTful APIs in their correct way but I think there are many problematic approaches for RESTful api design that does not leverage even HTTP protocol correctly. So in this article, I want to cover the essentials for RESTful API design especially referring to Richardson Maturity Model. Richardson Maturity Model(RMM), developed by Leonard Richardson, is a model that classifies thw REST approach into three fundamental elements:

  • Resouces
  • HTTP Verbs
  • Hypermedia Controls

1. Resources

We can classify the resources into two types: Instance resource and Collection resource. Instance Resource is an instance of an object similar to object instance in OOP(Object Oriented Programming) where a collection is collection of objects. It’s a plural name. For example /animals/dog can be seen as instance resource where /animals is a collection.

Resource is the fundamental concept in RESTful API design. Courses for a student enrolled to a class is a resource, Users for a website is a resource and etc. We can give many examples about it. On of the most debated topic in REST area is naming the resources. Resources should be based on Nouns not Verbs. For example, the followings are bad naming conventions consisting verbs:

  • /createUser
  • /giveMeTheBestMatch
  • /setHeight

Analyzing your business domain and extracting the nouns can be seen as the starting point of the REST api design. Once we define the resources (Nouns) we should define the behaviours/actions over that resources: get, create, update, delete. This is the second level in RMM explained in the following section.

2.HTTP Verbs (and Status codes)

HTTP is the foundation of data communication for the World Wide Web. HTTP defines a set of methods on the resource: GET, POST, PUT, DELETE, PATCH, HEAD and others. All these methods

GET means Read sth from server without side-effect(idempotent). DELETE means really Delete sth from server. And HEAD is a metadata operation. PUT and POST are used create and update operations and both of these methods can be used interchangebly for create/update operations with slight changes. I will not go into detail. I want to say only that PUT operation is an idempotent action.

  • GET /collections: Return a list of resources in the specified collection
  • GET /collection/:resource_id: Return an individual Resource object
  • POST /collection: Return the newly created Resource object
  • PUT /collection/:resource_id: Return the complete Resource object
  • PATCH /collection/:resource_id: Return the complete Resource object
  • DELETE /collection/:resource_id: Delete the resource and return an empty document

All actions have somehow some results on the server. All these results can be modeled again with HTTP Protocol’s status codes.

  • 2XX: Successful messages (200->OK, 201->Created)
  • 3XX: Traffic redirection (Most APIs do not use)
  • 4XX: errors made by the API consumer (400-> Bad Data, 404-> Not Found, 409->Conflict)
  • 5xx: Internal server errors (Exceptions in the server)

3. Hypermedia Controls

Have you heard about HATEOAS? HATEOAS is an acronym for “Hypermedia As The Engine of Application State” meaning that your web service is discoverable from a single base URL endpoint. That is, if someone knows your base url (https://api.yoursite.com) then that’s it! He knows about about your all endpoints ?! How? The answer is href. An endpoint will give some other endpoints urls(href) to go further with the returned results. I want to give an example from Stormpath’s API. If you make a call to list the groups, you will end up with a long json data. It lists all groups in order and each single group has some other endpoint url waiting to be discovered. For example, you will obtain detailed information of first element in the groups by calling https://api.stormpath.com/v1/groups/cquoM06qa6pTkk1h2xOeJ

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    href: "https://api.stormpath.com/v1/directories/5D1bvO5To6KQBaGFh793Zz/groups"
    offset: 0
    limit: 25
    items: [1]
      0:  {
        href: "https://api.stormpath.com/v1/groups/cquoM06qa6pTkk1h2xOeJ"
        name: "My Group"
        ... remaining Account name/value pairs ...
}

The third feature, Hypermedia Controls, is not a mandate for REST architecture. You can be RESTful without it strictly adhering to this principle. However, if you want to have a RESTful api, you should achieve the first two feature Resources and HTTP Verbs. There are many issues to create a RESTful API. I have listed some of them but haven’t eloborated them.

  • Base URL Selection (api.yoursite.com vs www.yoursite.com/api)
  • Versioning the API (api.foo.com/v1 vs. version data in the header)
  • Caching (Etag header)
  • Resource extensions (/applications/a1234.json)

References

comments powered by Disqus