Best Practices For Designing REST APIs (Part 1)
Tags: design, restapi
Published: 2019-09-25 19:22:19


When I started backend development I didn’t pay attention to best practices for developing web APIs and hence my first couple of projects were really a mess. There was no consistency for naming endpoints. I didn’t know how to deal with relationships or how a well-structured representation of a resource looked like. Hopefully, you would not have to go through this phase.

In this article, I’m only going to explain the  **Resource Representation**  of an API.

----------

# Resource Representation

Firstly, let’s explain what is “Representation” stands for. It could be defined as:

> Data that is returned when a client retrieved some resource from the server or sent from client to server.

User can view the representation of the resource in different formats. We call these formats  **Media Types**. All the available media types should encode the same data but just in different format. Out of all the available type, the most widely used one is  **JSON ( JavaScript Object Notation )**. JSON is simple, it’s that simple. This is the reason for it being used widely.

> JSON IS THE DEFACTO STANDARD FOR WEB API.

Apart from this, it also has some limitations like a limited data type. It does not support commonly used types like  _Date and Time_  and  _URL._ But we can still represent these type using  **_string_**.

**JSON Should Be Simple**

Didn’t I just say the JSON is simple? Well, one can make it harder to understand if standards do not meet. JSON is a collection of name/value pairs. The name itself is a string and it corresponds toa property of the resource. It should be kept in mind that a JSON should be self-explanatory. The picture below tells everything.

![](https://miro.medium.com/max/1125/1*E1IsMuPdFUg_NAGSYKoKpQ.png)

Notice that in the  **_complex_** example, ‘user-12348-as13s0-dsdf’ appears on the left of the colon in the position wherein a  **_simple_** example of JSON I have shown a property name. The JSON name  **data** also does not correspond to a property name

**How To Deal With Relations**

In almost every project, a resource has some kind of relationships and using simply named properties won’t be that helpful. Therefore, in your response representation, you should consider adding  **LINKS**. Let’s assume that  **JOHN** owns a Dog. Now, there exists a relationship between the owner and its Dog.

![](https://miro.medium.com/max/1125/1*IvXK_ZkRzXADDY4OuEpWPw.png)

Now both representations are valid. In the left,  _dogID_ is clearly describing some sort of relationship. But the representation in the right is more expressive and convenient. Why? Let’s assume that you just retrieved the response for John and now you want to get the dog which he owns. If you follow  **_without-links_**  example, you would have to look into the documentation (wish that the docs are up-to-date) to find a suitable endpoint and then construct that in your code to get his Dog(s). But with ‘**_with links’_**  example, you already know where to get the response. An increasing number of APIs from major companies on the web are including links in their data like Google and GitHub.

Now it’s maybe tempting to remove the  _dogID_ property from the response. Well, it all depends. Links tell us  _where we are and to where we should go._  But there may be some cases when you need  _dogID_  other than retrieving dog’s response.

**Companies Using Links**

Here’s the Google Drive API example:
  

    {
     "kind": "“drive#file",
     "id": "0B8G-Akr_SmtmaEJneEZLYjBBdWxxxxxxxxxxxxxxxx",
     "etag": "btSRMRFBFi3NMGgScYWZpc9YNCI/MTQzNjU2NDk3OTU3Nw",
     "selfLink": "https://www.googleapis.com/drive/v2/files/0B8G-Akr_Smt",
     "webContentLink": "https://docs.google.com/uc?id=0B8G-Akr_SmtmaEJneE",
     "alternateLink": "https://drive.google.com/file/d/0B8G-Akr_SmtmaEJne",
     "title": "Links.pdf",
     "mimeType": "“application/pdf"
    }