RESTfull

REST stands for REpresentational State Transfer and it’s not “web service framework”, but architectural style for web design, introduced by Roy Fielding in his 2000 doctoral thesis.
Fielding’s architectural style defines set of constraints that, if applied, can identify application as RESTfull. Those constraint are:

  • Resource identification through URI: Resources are identified by their URIs (typically links on internet). So, a client can directly access a RESTful Web Services using the URIs of the resources (same as you put a website address in the browser’s address bar and get some representation as response).
  • Uniform interface: Resources are manipulated using a fixed set of create, read, update, delete operations: PUT, GET, POST, and DELETE.
  • Client-Server: A clear separation concerns is the reason behind this constraint. Separating concerns between the Client and Server helps improve portability in the Client and Scalability of the server components.
  • Stateless: Each request from client to server must contain all the information necessary to understand the request, and cannot take advantage of any stored context on the server.
  • Cache: To improve network efficiency responses must be capable of being labeled as cacheable or non-cacheable.
  • Interconnected resource representations: the representations of the resources are interconnected using URLs, thereby enabling a client to progress from one state to another.
  • Layered components: intermediaries, such as proxy servers, cache servers, gateways, etc, can be inserted between clients and resources to support performance, security, etc.
  • Self-descriptive messages: Resources are decoupled from their representation so that their content can be accessed in a variety of formats, such as HTML, XML, plain text, PDF, JPEG, JSON, and others.
You can use the REST architectural style to build any type of web application, not just web services. But when you use it to build specifically web services then the result will be RESTfull web services.

You can adhere to the REST architectural type constraints as much as you want, but it’s not necessary to include all of them into your API design. Thus terms as “Not RESTfull”, “Not Fully RESTfull”, and “Completely RESTfull” have emerged. The best practice is to make your APIs as RESTfull as possible, but most importantly to make it easy to consume and maintain.

REST URI

URI stands for Uniform Resource Identifier and it’s what the web app uses to identify the target resource.

A Uniform Resource Locator (URL), commonly informally termed a web address (which term is not defined identically) is a reference to a web resource that specifies its location on a computer network and a mechanism for retrieving it. A URL is a specific type of Uniform Resource Identifier (URI), although many people use the two terms interchangeably. A URL implies the means to access an indicated resource, which is not true of every URI.

This Euler diagram shows that a Uniform Resource Identifier (URI) is either a Uniform Resource Locator (URL), a Uniform Resource Name (URN), or both.”
– Wikipedia

For example, a call to a REST service for single resource of type Person with by ID will look like this:

/persons/{personId}

A call to a REST server for retrieving collection of all resources of type Person don’t need an ID and may look like this:

/persons

Here are my guidelines for building descriptive URIs:

  1. First guideline: Resource based URI.
    The idea here is that resource based URI should resemble directory structure.

    /root/car
    /root/car/tire
    /root/car/seat
    /root/car/window

    The URI should “know the way” to the resource thru that structure. For example, it’s not OK to design API that gets all different types of resources from the root directory.

    /root/car
    /root/tire
    /root/seat
    /root/window

    Car tires reside within a car and the URI should reflect that.

  2. Second guideline: Noun instead of Verbs.
    URIs should not contain any verbs, but nouns, because verbs don’t resemble real directory. It may be tempting to use /getPerson instead of /person, but directory “getPerson” probably does not exist.

    Notice how well REST URI and HTTP work together. It’s almost as if HTTP is already integrated with REST concepts. That is because the creator of REST is also one of the principal authors of HTTP.
  3. Third guideline: Resource Relation.
    URIs should also show their relations with other objects. For example, if there is a Car object in the system, a nice URI of getting a single Car by ID would be:

    /cars/{carId}

    However, the system will also have a Tire object which is related to the Car object, because a car has 4 tiers. One way of getting specific Tire would be:

    /tires/{tireId}

    But that does not show the connection that Tire has to Car. So a proper and more descriptive URI will be:

    /cars/tires/{tireId}

    Now, the URI shows the connection between Car and Tire objects. However, this URI look like it gets you specific tire, but for all cars, which is not ideal. You would want to be able to specify the car and the tire for that car. So a better URI will look like this:

    /cars/{carId}/tires/{tireId}

    The Car object is called first level entity because the URI starts with it. The Tire object is called second level entity, because, in this specific model, to get to Tire the client must got thru the Car object.

    The same model can be applied to all car related objects:

    /cars/{carId}/seats/{seatId},
    /cars/{carId}/windows/{windowId},
    /cars/{carId}/repairBills/{repairBilId}.

    As nice and organized as this descriptive model may seem to be it has its drawbacks, because now in order to get a Tire information, the client has to know not only the Tire ID, but also the Car ID. This is where some design decisions have to be made. If it’s safe to assume that the Tire will always know about the Car ID, then using the more descriptive model will be OK. But in the other case, it’s better to stay cryptic and just design URI that only knows about the Tire itself.

    Most cars also have license number so license URI may look like this:

    /license/{licenseId}

    Now you are about to say: “Hey, why didn’t you show the relationship between Licence and Car objects. Surely, a Car has a Licence, so why treat License as a separate entity?”

    Well, it’s simply because I choose not to couple Car and Licence objects in my design. And I did that because I don’t think the client app will always know Car’s licence.

    Still, those are just guidelines and REST doesn’t have any specific rules about how the URI should look or what parameters should it carry. It all depends on the implementation of the web service consumer. As a matter of fact, when it comes to REST Web Services there are no strict rules at all. As long as the client and the service understand each other – all is fine.

HTTP Methods

So far, you know how to construct URI to identify a resource, but how to specify the operation on that resource?

Request methods make clear what kind of operation the client expects the service to perform. The most common operations usually resembles the CRUD actions: Create (POST), Read (GET), Update (PUT), and Remove (DELETE).

Why did I use POST for create and PUT for update and not the other way around, you may ask. There is a lot of arguing on the internet about the roles of those methods coming from the fact that they are almost, if not, 100% interchangeable. Any of them will do the work for you – PUT can be configured to create and update, but so can POST.

Personally I prefer to use POST when creating new entities, because:

  1. POST is designed to carry information about the entities in its body, unlike PUT.
  2. PUT seems to be URI driven, meaning that any information about the object (like ID) will reside in the URI (/cars/{carId}). That makes PUT ideal for updating existing entities, because the client will know about their IDs. It just so happens that this is the common practice anyway.
  3. POST is not idempotent, which generally means that the same POST call (/cars) is allowed to return different result each time is’t called, but will get to that later.

Since the method specifies the action for particular request, there is no need to include that information in the URI and REST takes full advantage of that. For example, the URI for getting a Car entity can be also used for updating or deleting it:

/cars/{carId}

The difference comes from the HTTP Methods in the request.

To fetch Car entity: HTTP GET

/cars/{carId}

To fetch Tire entity: HTTP GET

/cars/{carId}/tires/{tireId}

To update Car entity: HTTP PUT

/cars/{carId}

To update Tire entity: HTTP PUT

/cars/{carId}/tires/{tireId}

To delete Car entity: HTTP DELETE

/cars/{carId}

To delete Tire entity: HTTP DELETE

/cars/{carId}/tires/{tireId}

In order to delete whole list of entities, the HTTP Methods have to be applied on collection level URI:
To delete all Car entities: HTTP DELETE

/cars

To delete all Tire entities related to a specific Car: HTTP DELETE

/cars/{carId}/tires

Creating new Car entity is a bit tricky, because normally the DB is assigning IDs to new entities, not the client web app. So in this case, the URI should look like this:
To create new Car entity: HTTP POST

/cars

To create new Tire for existing Car entity: HTTP POST

/cars/{carId}/tires

The service can now return the newly created ID into response body for further updates.

Notice that creating entities is applied on collection level URI.

Again there are no strict rules which method should be used over another, only few guidelines depicted in the table below.

Method

Operation performed on server Role

Quality

GET Read a resource. Read Safe & Idempotent
PUT Insert a new resource or update if the resource already exists. Write Idempotent
POST Insert a new resource. Also can be used to update an existing resource. Write N/A
DELETE Delete a resource . Write Idempotent
OPTIONS List the allowed operations on a resource. Read Safe
HEAD Return only the response headers and no response body. Read Safe

Safe: are HTTP methods that do not modify the resources they are used on. For example, using GET or HEAD on a resource URL, should NEVER change the resource.

Idempotent: the definitions is that URI can be called many times providing always the same result. It would not matter if the method is called only once, or ten times over. PUT and DELETE are idempotent, because the first call do the actual update and any subsequent call for the same URI will not result in any practical change.

POST is the only methods that is not idempotent or save by definition. That is one more reason why it should be used to object creation – it will create new object every time the URI is called.

The PUT and DELETE methods are defined to be idempotent. However, there is a caveat on DELETE. The problem with DELETE, which if successful would normally return a 200 (OK) or 204 (No Content), will often return a 404 (Not Found) on subsequent calls, unless the service is configured to “mark” resources for deletion without actually deleting them. However, when the service actually deletes the resource, the next call will not find the resource to delete it and return a 404. However, the state on the server is the same after each DELETE call, but the response is different.

Content Negotiation

So far, your app knows how to build URI and which HTTP Method to use in order to interact with the web service, but what format will it use for communication? The web service may or may not be expecting client’s particular format. As I mentioned before REST doesn’t have any strict rules for web service design as long as the client and service can understand each other. So the proper way to ensure the right communication format is with Content Type header value.
This isn’t a big surprise for experienced web developers, but it was worth mentioning.

Each HTTP request needs to set it’s Content-Type header value so the web service can extract it and later parse its response into that format.
Also each response can set the same header in order to notify the client about its actual content.
There are many predefined values for this header tag, but the most popular ones are “text/xml” for XML content and “application/json” for JSON type.

HTTP Status Codes

So far, you app can build URIs, and use HTTP methods to send HTTP Requests with proper Content-Type to the web service. What about web service’s response?

The traditional human-to-machine architecture will ultimately deliver human readable text, but since web services are not serving humans, but machines instead, human readable text is useless. So instead, HTTP Status Codes are returned. You can still have text in the response body of course, but the Status Code is what should really matter for the client.

The standard HTTP Status Codes apply here as well:

  • 1XX – informational
  • 2XX – success
  • 3XX – redirection
  • 4XX – client error
  • 5XX – server error
Method Typical Usage Typical Status Codes
GET retrieve a representation
OR
retrieve a representation if modified (caching)
200 (OK) – the representation is sent in the response
204 (no content) – the resource has an empty representation
301 (Moved Permanently) – the resource URI has been updated
303 (See Other) – e.g. load balancing
304 (not modified) – the resource has not been modified (caching)
400 (bad request) – indicates a bad request (e.g. wrong parameter)
404 (not found) – the resource does not exists
406 (not acceptable) – the server does not support the required representation
500 (internal server error) – generic error response
503 (Service Unavailable) – The server is currently unable to handle the request
DELETE delete the resource 200 (OK) – the resource has been deleted
301 (Moved Permanently) – the resource URI has been updated
303 (See Other) – e.g. load balancing
400 (bad request) – indicates a bad request
404 (not found) – the resource does not exits
409 (conflict) – general conflict
500 (internal server error) – generic error response
503 (Service Unavailable) – The server is currently unable to handle the request
PUT create a resource with client-side managed instance id
OR
update a resource by replacing
OR
update a resource by replacing if not modified (optimistic locking)
200 (OK) – if an existing resource has been updated
201 (created) – if a new resource is created
301 (Moved Permanently) – the resource URI has been updated
303 (See Other) – e.g. load balancing
400 (bad request) – indicates a bad request
404 (not found) – the resource does not exits
406 (not acceptable) – the server does not support the required representation
409 (conflict) – general conflict
412 (Precondition Failed) e.g. conflict by performing conditional update
415 (unsupported media type) – received representation is not supported
500 (internal server error) – generic error response
503 (Service Unavailable) – The server is currently unable to handle the request
POST create a resource with server-side managed (auto generated) instance id
OR
create a sub-resource
OR
partial update of a resource
OR
partial update a resource if not modified (optimistic locking)
200 (OK) – if an existing resource has been updated
201 (created) – if a new resource is created
202 (accepted) – accepted for processing but not been completed (Async processing)
301 (Moved Permanently) – the resource URI has been updated
303 (See Other) – e.g. load balancing
400 (bad request) – indicates a bad request
404 (not found) – the resource does not exits
406 (not acceptable) – the server does not support the required representation
409 (conflict) – general conflict
412 (Precondition Failed) e.g. conflict by performing conditional update
415 (unsupported media type) – received representation is not supported
500 (internal server error) – generic error response
503 (Service Unavailable) – The server is currently unable to handle the request

Links & Resources

JavaBrains YouTube series on Developing RESTful APIs with JAX-RS
InfoQ designing restful http apps article
Spring IO topic on understanding REST
Drdobbs’s tutorial on RESTful Web Services
java2blog.com – RESTful web service tutorial
Wikipedia CRUD operations definition
World Wide Web Consortium definition for HTTP Methods
restcookbook.com article on POST vs REST

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s