Characteristics of Good REST Services

September 23, 2012 — 4 Comments

REST (Representational state transfer) Services play an important role in today’s interconnected systems. By exploiting HTTP, a well-known protocol, they enable applications of all types to easily exploit these service.

REST attempts to describe an architecture that use HTTP or similar protocols by constraining the interface to a set of well-known, standard operations (like GET, POST, PUT, DELETE for HTTP). Here, the focus is on interacting with stateless resources, rather than messages or operations.

They Must Follow Standards

When I say that REST services must follow standards, I mean that they need to follow what is accepted by the general community. The following are the Levels of REST. A service can only be considered RESTful if all of these levels are present.

 

1

POX (Plain Old XML)

XML – means Extensible Markup Language
JSON – means JavaScript Object Notation
BSON – is based on the term JSON and stands for “Binary JSON”
Protocol Buffers – a method of serializing structured data

Using lightweight formats to represent resource state will greatly benefit your service by reducing the size of the data transferred. Resulting in faster response times and a better end client experience.

Resource Representational States Should Only Contain The Required Data

This is quite important. Large Resource Representational State objects incur costs on many levels. They take up more bandwidth, they reduce the responsiveness of the service and they provide much more then was intended or communicated by the URI. Bloated Resource Representational State are a good indicator that some refactoring may be in order.

Resource Representational States Should be Versioned!

There are great debates about how to version RESTful Services. One way to accomplish this, is by encoding the version in the ACCEPT header of your requests. The server will then be able to read this header and select the proper strategy to deserialise the payload using the supported version. This server side behavior needs to be implemented by the service developers.

2 Resources

Resources map named concepts to entities through time.
Many-to-Many relationships tie concepts and entities.
The relationships can change frequently through time
or they can remain stable.

Focusing solely on creating beautiful URIs (Uniform resource identifier) does not make your service RESTful, it can actually produce the opposite result. REST does does not prescribe a URI structure. Therefore, it is up to the service designer to come up with a standard template, which should be constant and therefore predictable. Service designers can further assist consumers by creating URIs do what they say.

Service designers can further embellish consumer experience by  implement paging for long lists. They can also follow two rules to help limit regressions to a maximum.

1) Once a URI (endpoint) is published, it is better to create a new URI than to change the signature of an existing URI.

2) To accommodate changes it is preferable to deprecate older URI versions early and to strongly recommend that consumers use the new URIs.

In the end all that really matters when it comes to URIs, is that their style consistent and clearly communicate intent. Throughout the design process style matters and the guidelines to a beautiful and functional RESTful service strongly resemble those of clean code.

The Following Are URI Template Examples :

http://localhost/api/tasks
http://localhost/api/tasks/(?id)
http://localhost/api/tasks/backlog
http://localhost/api/tasks/in-progress
http://localhost/api/tasks/completed

3

HTTP Verbs

Using HTTP Verbs alone does not make a service RESTful but it does make you that much closer. Using these verbs conforms to known standards, making your service predictable. Using HTTP further empowers the service designers to exploit the returnHTTP Status Codes to clearly communicate errors.

For example, by using the GET verb the consumers know that they don’t alter the state of the system. On the other hand, if the consumers use the POST verb they know that they are significantly altering the system’s state.

 

GET

– use it to fetch a resource

The GET verb denotes the only method that can be cached at multiple levels. Resources can be cached at the origin, at the client and in between. Network devices can participate in the caching strategy, in turn significantly reducing the load on the origin service.

POST

– use it to create a resource

The POST verb denotes the creation of a resource. This method is not cacheable and is the most dangerous of all. Using this method guaranties that the system state will be modified.

It can also be used to push data to the service. When the service receives the data, it can create a new resource returning the URI corresponding to the new resource. It can react to the received data in various unpredictable ways.

PUT

– use it to update a resource

The PUT verb denotes the modification of a resource state. The difference between PUT and POST, is that PUT modifies the resource state in an idempotent manner. No matter how many times a PUT gets executed, the outcome is always the same and predictable.

PUT allows you to push a resource to a specific URI. If the resource does not exist it creates it. If it exists it replaces it.

DELETE

– use it to remove a resource

HEAD

– use it to retrieve meta-information without the response body

The HEAD verb is very useful. It can be used to  fetch E-Tags and other meta-information for specific resources without the full representational state of the requested resource. This empowers the consumers to verify if a specific resource has been modified since the last time it was fetched. Further more, this is a great trick to help reduce the amount of data required to travel over the network for each request.

PATCH

– use it to make partial modifications to resources

Rarely have I seen this verb used but I’m sure it comes in handy when a consumer is required to send a delta of the original and the modified representational state to the server. In turn reducing the amount of data required to travel over the network and giving the consumer a better experience.

4

Hypermedia

A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand).

~ Roy Fielding

This is by far the most forgotten part of RESTHyperMedia is the heart of RESTful services. As Roy Fielding put it, HyperMedia empowers the consumers. It allows the consumer to discover functionality. It also allows them to be flexible and have less dependencies on actual URIs by having the service construct and serve named URIs to the client. The client can use the URI names to extract and match URIs to specific actions that are contextual to resources.

HAL – Hypertext Application Language is a great way to represent HyperMedia in RESTful services. Imagine a service for which, you as a consumer, would only need to create a single deseriaszation  strategy that would accommodate all possible responses. HAL provides us with this generic contract.

HAL is a simple way of linking with JSON or XML.

It provides a set of conventions for expressing hyperlinks to, and embeddedness of, related resources – the rest of a HAL document is just plain old JSON or XML.

HAL is a bit like HTML for machines, in that it is designed to drive many different types of application. The difference is that HTML is intended for presenting a graphical hypertext interface to a ‘human actor’, whereas HAL is intended for presenting a machine hypertext interface to ‘automated actors’.

It encourages the use of link relations to:

  • Identify links and embedded resources within the representation
  • Infer the expected structure and meaning of target resources
  • Signalling what requests and representations can be submitted to target resources

The following example has been taken from Mike Kelly’s blog

{
  "_links": {
    "self": { "href": "/product/987" },
    "upsell": [
      { "href": "/product/452", "title": "Flower pot" },
      { "href": "/product/832", "title": "Hover donkey" }
    ]
  },
  "name": "A product",
  "weight": 400,
  .. *snip* ..
}

This example demonstrates a standard that facilitates the packaging of contextual links with resources. Bellow is a schema who’s goal is to graphically demonstrate this example’s document structure.

info-model

HAL has two main components: Resources and Links.

  • Resources can have their own state, links, and other embedded resources.
  • Links have a link relation (rel) that signals how to interpret the target resource.

HAL Resources

      Download

HAL

      from

Nuget

      :

https://nuget.org/packages/Hal.NET

      Playing around with

HAL

      I felt that something was missing which I found in the following sample of

HyperMediaHTML

      . Notice how the service is able to communicate the

POST

      contracts through the forms generated by the server. These contracts can then be parsed and used by applications. It also results in a

REST

    service that is easy to test through a browser.

image

So I asked Darrel Miller how he would go about exposing these kinds of contracts and he directed me to this project on GITHub by Mike Kelly which seems really promising.

{
  "_links": {
      "self": { "href": "/" },
      "basic": { "href": "/bleh" },
      "search": { "href": "/search_for;{searchTerm}" }
    },
  "_controls": {
    "order": {
      "href": "http://...",
      "method": "POST",
      "template-type": "http://shishkin.org/json-templates",
      "template": {
        "location": "",
        "@location": {
          "prompt": "Enter your postal code"
        },
        "pickupTime": "",
        "@pickupTime": {
          "prompt": "When do you want to pickup your order?",
          "type": "dateTime"
        },
        "items": [
          {
            "name": "espresso",
            "@name": { "options": [ "espresso", "cappuchino", "latte" ] },
            "size": "normal",
            "@size": { "options": [ "normal", "grande", "venti" ] },
            "additions": [],
            "@additions": {
              "multiple": true,
              "item": "string",
              "options": [ "shot", "caramel", "vanilla", "decaf" ]
            }
          }
        ]
      }
    }
  }
}

I might have named the “controls” collection differently. “contracts” might be a better name for what I was looking for.  This looks like a great way to provide enough information for the consuming application to generate the data entry screens. Its also a great source of information about how to communicate with the service. How many times have you come in contact with a badly documented service, where contracts between the service and the consumer are at best shady…

For those of you who will be looking into HAL for HyperMedia I would really appreciate your feedback in the comments bellow.

 

They Must be Fully Tested

The services’ interfaces should thoroughly documented and it should always kept up to date. A great way to accomplish this, is by documenting them in a wiki. Wikis make it easy to version documentation and to crossed reference it. They also make it very easy to make available to consumers.

There are no acceptable reasons NOT to fully test a RESTful service. Tests eventually become the truth about your service. They provide a way to gauge changes performance and quality. They also permit the designers to find problems in their designs.

And lastly, tests provide an amazing tool to teach others how to use your services. They’re working examples that show consumers how to properly use them. But above all it’s your chance to promote best practices!

4 responses to Characteristics of Good REST Services

  1. 

    Intéressant, j’imagine que tu as récemment eu à jouer avec de la programmation dynamique de découverte de service et ressource avec HAL ;)

    Like

  2. 

    You meant idempotent, not omnipotent.

    Like

Trackbacks and Pingbacks:

  1. Links of interest | Louis Turmel Blogs - April 21, 2014

    […] Ok, I’m also learning about how to implement a great MVC API for one of my project. It’s easy to design and code doing work between the client and the server, but I’ve to admit it, my MVC API wasn’t RESTful. So I had to come back to the base of it. Alexandre Brisebois explains it clearly by his post “Characteristics of Good REST Services“. […]

    Like

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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.