REST-Based API Design

This is a continued blog post series. You can find the first post here.

Resumé of chapter 1

The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.

— Roy Thomas Fielding

Chapter 7 starts with this quote. Hmm how many know this. I often hear people talk about REST as synonymous with any http based Remote Procedure Call (RPC) API. But WORDS has specific meaning. And here we are talking about REST, in its original meaning, suitable for hypermedia data transfer.

If you ever wanted to know what REST really means then this chapter is for you.

The chapter explains the following truth’s about REST:

REST is about distributed systems

REST was defined in a dissertation by Roy Fielding. James encourage us to read it since its not only about API’s but as much about constraints for evolvable distributed systems.

REST was never about CRUD 

Even though many people associate REST with JSON based Create, Read, Update, Delete (CRUD) style API, this was never the essence of REST.

REST Is Client/Server

The fact, that the Client is separated from the sever, gives a high degree of decoupling and evolvability. The Client User Interface can change with out affecting the Server. This makes an API suitable for a generic product, since multiple clients can define different user interfaces.

REST Is Resource-Centric

A resource is a digital representation of a real world concept or thing. Just like we have modelled entities in previous chapters. The representation of the resources  may be in a format such as JSON, XML, CSV, PDF, image, and other media types.

REST Is Message Based

Keep in mind that an API is a conversation. Focusing on the message aspect of REST is important, as the chapter articulates here:

“Readers of Fielding’s dissertation may have noticed that it focuses on the message exchange between client and server. Notice the use of the terms REST messages and self-descriptive messages in the paper. REST-based API design goes beyond the properties within a JSON or XML representation.”

The request is a command that tells the server what to do.

However, other parts than the message body must not be neglected. The URL path, URL query parameters, and HTTP request/response headers must all be considered as part of the design process. Focusing only on the message body results in an incomplete design.

REST Supports a Layered System

Many API implementations never comes beyond the JSON, CRUD level and never gets to caching and other middleware that http and REST supports. The design should allow middleware to do caching, rate limiting, authentication and load balancing.

REST Supports Code on Demand

This part explains that REST supports the ability for the client to request code from the server that it can then execute. This is an often unused but power full capability. I Find this pretty interesting! As James explains, it’s an underutilized feature of REST. The server can offer executable code that the client can request.
An example is java script that browsers download to execute locally.
This is extensible, since new code can be served without breaking existing clients.
In principle, an API could offer complete client side code to support input forms and validation. 

Hypermedia Controls

Hypermedia and HATEOAS gets explained. HATEOAS gives the client possibility for machine based discoverability. Most readers will probably know about REL links that links to related resources and permitted actions. But other kinds of hypermedia controls exist as well.

  • Index hypermedia controls: Offer a list of all available API operations, typically as an API homepage.
  • Navigation hypermedia controls: Include pagination links within payload responses or by using the Link header.
  • Relationship hypermedia controls: Links that indicate relationships with other resources or for master-detail relationships.
  • Context-driven hypermedia controls: Server state that informs the client what actions are available

 

It is the fact, that each resource has a unique URL in REST, that allows for hypermedia controls. This is an advantage that the REST API style has over other  styles like GraphQL, gRPC and older network API styles and messaging specifications such as SOAP and XML-RPC.

When to choose REST

Choose REST for generic API, that allow independent development of multiple clients. 

Consider gRPC when performance needs to be improved, but at the cost of closer coupling between client and server. 

Consider standard RPC, for simplicity and if the payload is optimized for a specific client side application.

A REST API can be supplemented with a query API like graphQL. 

REST API Design Process

The bulk of the modeling work has all ready been done in chapter 6 (API Modeling). The tangible artefact from the API Modeling proces was the socalled API Profile. Which contains information about the API that is agnostic to a specific Implementation.
 
This chapter suggest a quick 5 step process to reach a REST API Design.
 The 5 steps are listed in the illustration below.
rest api design process
Step 1: Design Resource URL Paths

Create a new table for the REST API Design. Define the resource path for each operation. Tip: Only use nested resources if it improves the design. When doing a bottom up design from a database one could be tempted to design URL’s as nested resources like the following: 

				
					GET /users/{userId}/projects/{projectId}/tasks/{taskId}
				
			

Often it’s better to avoid this since it makes it more complicated for the client. In the example above, the taskId is unique anyway and the task can be retrieved with out supplying the userId and projectId.

Step 2: Map API Operations to HTTP Methods

You need to assign http verbs like POST, GET etc.. This section gives in depth guidance on when to use what. Add the Http methods in a new column in the schema.

Step 3: Assign Response Codes
The Section suggests to always use standard codes and not invent any yourself.
Deliberately think about what the response codes should be. Add the Response code to a Response column in the schema.
Step 4: Documenting the REST API Design

Chapter 13 goes into detail about various documentation formats. One such format the OpenAPI Specification, 

which can be read and written using swagger

The important point is to supply a machine readable documentation format, so one can take advantage of all the tooling like code generators and html generators for visualizing the documentation.

Another recommendation is to make sequence diagrams to validate the model. Remember that an API is a conversation between the user and the System. Make sure that the API operations allows for a natural flow that in the end yields a useful outcome for the user.

Step 5: Share and Gather Feedback
Make sure you present the API to stakeholders and get feed back. When an API has been released its locked. Changing the API after release could break clients. So Do proper review and avoid having to immediately make a new revision.
 

Representation Format

 

The chapter suggests 4 different representation format categories.

CategoryOverview
Resource SerializationThe representation reflects the serialization of a resource into various formats, e.g., JSON, XML, Protocol Buffers, and Apache Avro
Hypermedia SerializationA serialized representation with support for embedded hypermedia controls
Hypermedia MessagingA general message format that supports resource properties with hypermedia controls
Semantic Hypermedia MessagingA general message format that supports semantic field mapping with hypermedia controls
 

 

Resource Serialization
Often a  resource serialization representation format has been decided upon. Typically JSON now adays. But in case one would need to change to another format, content negotiation allows to support multiple formats, and an operation  by operation migration to an new format is possible. 

New binary formats are protocol buffers and apache avro

Hypermedia Serialization
The different representation categories are extensions on top of the previous one.
 
Hypermedia serialization adds specification on how hypermedia links are represented.
 
the HAL format is one such specification. Other formats gets presented like Mike Amundsen’s H-Factors.
 
 Below is a HAL Example from the chapter. Notice the _links sections.
  
				
					{
    "bookId": "12345",
    "isbn": "978-0321834577",
    "title": "Implementing Domain-Driven Design",
    "description": "With Implementing Domain-Driven Design, Vaughn has made an
important contribution not only to the literature of the Domain-Driven Design
community, but also to the literature of the broader enterprise application
architecture field.",
    "_links": {
        "self": { "href": "/books/12345" }
    },
    "_embedded": {
      "authors": [
        {
          "authorId": "765",
          "fullName": "Vaughn Vernon",
          "_links": {
             "self": { "href": "/authors/765" },
             "authoredBooks": { "href": "/books?authorId=765" }
          }
        }
      ]
    }
}
				
			
 
Hypermedia messaging
While hypermedia serialization specifies how to represent relationships between resources by means of self and rel links. Hypermedia messaging goes the next step and offers specification on how to represent the resources themselves. 
 
This offers a uniform way of parsing data, so one parser can be used for all entities. While the format might add some complexity, there is a  huge advantage in settling for a format, like James puts it. 
 
“consider that teams will no longer need to argue about what the JSON or XML payload should look like. Instead, they focus on the resource representations, relationships, and hypermedia controls within the message format itself. No more meetings to decide if a data wrapper is required around a JSON-based response!”
Two formats gets mentioned jsonapi and siren
Semantic Hypermedia messaging
Semantic hypermedia messaging is the most comprehensive category, as it adds semantic profile and linked data support, making APIs part of the Semantic Web.
Web 1.0 was about linking webpages. Web 2.0 was about lining web applications. web 3.0 is about linking data. And for that we need a common format.
 
Various formats gets listed
Below is a data snippet giving an impression of the UBER format.
 
				
					{
  "uber" :
  {
    "version" : "1.0",
    "data" :
      [
        {"rel" : ["self"], "url" : "http://example.org/"},
        {"rel" : ["profile"], "url" : "http://example.org/profiles/books"},
          {
            "name" : "searchBooks",
            "rel" : ["search","collection"],
            "url" : "http://example.org/books/search?q={query}",
            "templated" : "true"
          },
          {
              "id" : "book-12345",
              "rel" : ["collection","http://example.org/rels/books"],
              "url" : "http://example.org/books/12345",
              "data" : [
                {
                  "name" : "bookId",
                  "value" : "12345",
                  "label" : "Book ID"
                },
                {
                  "name" : "isbn",
                  "value" : "978-0321834577",
                  "label" : "ISBN",
                  "rel" : ["https://schema.org/isbn"]
                },
                {
                  "name" : "title",
                  "value" : "Example Book",
                  "label" : "Book Title",
                  "rel" : ["https://schema.org/name"]
                },
                {
                  "name" : "description",
                  "value" : "With Implementing Domain-Driven Design, Vaughn
has made an important contribution not only to the literature of the Domain-
Driven Design community, but also to the literature of the broader enter132prise
application architecture field.",
                  "label" : "Book Description",
                  "rel" : ["https://schema.org/description"]
                },
                {
                  "name" : "authors",
                  "rel" : ["collection","http://example.org/rels/authors"],
                  "data" : [
                    {
                      "id" : "author-765",
                      "rel" : ["http://schema.org/Person"],
                      "url" : "http://example.org/authors/765",
                      "data" : [
                        {
                          "name" : "authorId",
                          "value" : "765",
                          "label" : "Author ID"
                        },
                        {
                          "name" : "fullName",
                          "value" : "Vaughn Vernon",
                          "label" : "Full Name",
                          "rel" : "https://schema.org/name"
                        }]}]},
               ]}]}}
				
			

Common REST Design Patterns

I’m nearly replicating the whole book. 

James lists 5 different REST design patterns

  • Create-Read-Update-Delete
  • Extended Resource Lifecycle Support
  • Singleton Resources
  • Background (Queued) Jobs
  • Long-Running Transaction Support in REST
 

You should really get the whole book

Summary

A really extensive chapter, that shows how  many possibilities REST offers. Something that many companies and people are not utilizing or are not even aware of.

The chapter is an eye opener in this regard and explains REST. The subject is big, which the amount of linked resources suggests; resources that we can explorer further. What we have by now, is a great overview and an overall understanding of what REST really is.