Five aspects of RESTful API design

Tags: rest, api, raml, restful
Published: 2020-08-03 12:21:34

There are five principal aspects to a RESTful API specification that must be considered prior to coding an API specification.

In this post I will discuss those five features with examples using a product use case. 

If you are already familiar with API design and want to go deeper, I suggest that you take a look at the tutorial: [How to design RESTful APIs with the API Designer](https://developer.mulesoft.com/tutorials-and-howtos/quick-start/designing-your-first-api?utm_source=dev.to&utm_medium=link-top&utm_campaign=J2M&utm_term=RESTful%20API).

Before I get started let's ensure that we understand what is meant by API and REST.

## What is an API?

An Application Programming Interface (API) is a set of rules that define how a software component can interact with another software component. 

In the context of a web service those interactions relate to the manipulation and retrieval of data in accordance with the four basic functions of persistent storage: create, read, update, and delete (CRUD). 

The style in which these rules are defined is referred to as the **“REST architectural style”**. This was devised by Dr Roy Fielding in his 2000 PhD dissertation [“Architectural Styles and the Design of Network-based Software Architectures”](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm). 

## What is REST?

REST stands for REpresentational State Transfer. It provides a way to represent resources (i.e. data) and transfer it over HTTP by calling a URI. The URI represents the data as a noun and the data function (CRUD) is represented by an HTTP method. Typically the HTTP methods map to CRUD functionality as should in the following table.

| CRUD functionality  | HTTP method  |
|---|---|
| GET   | Read  |
|  POST | Create  |
| PUT / PATCH  | Update / Partial update  |
| DELETE   | Delete  |

## RESTful API spec design

The API designer has a choice of RESTful modeling languages to use for the implementation of the API design. Here are two of the most widely used:

* OAS (Swagger)
* RAML (RESTful API Modeling Language)

Each has its own approach to specifying as API design and each with its pros and cons, nevertheless they both respect the REST architectural style. 

I choose to use RAML in this blog post as I believe it's the most intuitive modeling language available for those that are not familiar with API modeling languages. 

The REST API design tool that I will use in this article is the highly productive tool used in the tutorial [How to design your first API with API Designer](https://developer.mulesoft.com/tutorials-and-howtos/quick-start/designing-your-first-api?utm_source=dev.to&utm_medium=link-middle&utm_campaign=J2M&utm_term=RESTful%20API) from MuleSoft. This tool is ideal for designing RESTful APIs with RAML or Swagger (OAS 2 and 3). However you can use whichever tool suits you.

### The product use case 

To add context to the specification I will define a use case. Let's imagine that our company has asked for an API that represents product data. The REST API will expose functionality that in accordance with full CRUD functionality and the API specification must documentation the product data type and provide examples.

Let’s get started by defining the header of the API specification.

## Define the API header

I will start by defining the header of the specification file in which I define the API title (for display purposes), the asset version, and the base URI at which the implementation will be deployed.

```
#%RAML 1.0
title: Products API
baseUri: http://big-product-company.com/api/{version}
version: v1
```

Next, I will define the resource representation for our products.
Define the resource URIs

The resource URIs represent the product data and it is these URIs against which CRUD functionality can be performed, thus representing the actions for Create, Read, Update and Delete.

In order to respect the REST conventions, the resource URIs are named as nouns that relate to the actual data it represents. Common resources might be represented as shown in the table below:
Resource URL

| Resource URL  | Data type  |
|---|---|
|  /accounts  |Account data |
|  /invoices  |Invoice data |
|  /users  |User data |

The expectation of the REST style is that a call to the GET /products endpoint will return a list of products (even if the response contains only one product) and therefore, as the resource represents a collection, the nous is pluralized. The RAML syntax states that the resource URI must be terminated with a colon `:`

`/products:`

Once the resource URI is defined, the CRUD functionality that we want to operate on those resources, is specified using HTTP methods.

## Define HTTP methods for resource URIs

As shown above, there are five HTTP methods defined for use by developers of REST API specifications. 

The REST style states that the GET and POST HTTP methods are used with a single URI resource as they don’t target an identifiable resource but rather a list of resources. Conversely, the DELETE, PUT and PATCH HTTP methods are accompanied with a URI variable that identifies the resource being affected. Take a look at the code below. 

```
/products:
 get:
 post:
 /{productID}:
   put:
   delete:
```

Notice how the GET and POST methods are used with the `/products` URI and the PUT and DELETE are used with the `/products/{productID}` URI.

The POST and PUT endpoints must include a resource presentation, in our case a product to create (POST) or update (PUT). The request body must be defined in the specification so it is clear to the caller what data must be sent and in what format.

## Define the HTTP requests

To satisfy the REST requirement for clear resource representation the API spec must define a data type and provide a valid example of the data. In our case this will be a data type that defines the structure of the product and an example.

It is also a requirement (actually its a strong recommendation) to specify the data interchange format. Typically this is defined as a MIME type, such as JSON and XML, and can be one of many types.

For our use case lets add an example to each endpoint and define a MIME type. 

In the RAML below the product GET, POST and PUT endpoints are defined with an example of the product data for the POST and PUT. The data interchange format is defined as `application/JSON`.

```
/products:
 get:
 post:
   body:
     application/json:
       example: |
         {
           "name" : "Bed",
           "price" : "100"
         }
 /{productsID}:
   put:
     body:
       application/json:
         example: |
           {
             "name" : "bed",
             "price" : "100"
           }
   delete:
```

For each request made to the API and response is expected and should be defined in the RESTful API specification. Let’s take a look at how this is done.

## Define the HTTP responses

In response to a request the caller expects to receive a body containing data (or at least a message) and an HTTP status code indicating the status of the requests. HTTP status codes fall into one of five categories as show here:

* 1xx  ->  Informational
* 2xx  -> Success
* 3xx  -> Redirection
* 4xx  -> Client Error
* 5xx  -> Server Error

The first digit of the status code identifies the status of response. A full list of status codes can be found here.

For our product example let’s define a response for the GET and DELETE methods. I am going to define a 200 code for the GET and DELETE request to indicate a successful operation.

```
/products:
 get:
   description: Retrieve the list of all products
   responses:
     200:
       body:
         application/json:
           example: |
             {
               "name" : "Bed",
               "price" : "100"
             }
 post:
 /{productID}:
   put:
   delete:
     responses:
       200:
         description: Delete the product with id {productID}
```

Now we have defined all the main aspects of an API specification let’s put it all together.

## Putting it all together

The complete RESTful API design looks as follows:

```
#%RAML 1.0
title: Products API
baseUri: http://big-product-company.com/api/{version}
version: v1

/products:
 get:
   description: Retrieve the list of all products
   responses:
     200:
       body:
         application/json:
           example: |
             {
               "name" : "Bed",
               "price" : "100"
             }
 post:
   body:
     application/json:
       example: |
         {
          "name" : "Bed",
          "price" : "100"
         }
 /{productID}:
   put:
     body:
       application/json:
         example: |
           {
             "name" : "Bed",
             "price" : "100"
           }
   delete:
     responses:
       204:
         description: Delete the product with id {productID}
```

## Final thoughts

In this tutorial I have shown five aspects of API specification design using RAML as the RESTful API modeling language. I have covered how to define resources, methods, requests and responses in accordance with the REST architectural style.

If you want to dive deeper into API design I recommend you take a look at the [How to design your first API with API Designer](https://developer.mulesoft.com/tutorials-and-howtos/quick-start/designing-your-first-api?utm_source=dev.to&utm_medium=link-bottom&utm_campaign=J2M&utm_term=RESTful%20API) tutorial.