API Design Best Practices

API Design Best Practices

Timo
Timo

I. Agenda

  1. Agenda
  2. Overview
  3. What is an API?
  4. Rules for Restful API URI design
  5. HTTP methods
  6. HTTP response status codes
  7. Sub and nested resources
  8. Other useful operation
  9. The API version

II. Overview

The purpose of this post is to share my knowledge and experience in designing and working with RESTful API. In these days in software development, RESTful API has more benefits compared to other concepts.

III. What is an API?

An API (application program interface) is a set of rules that enables different programs to communicate with one another. It outlines the appropriate way for a software developer to compose a program on a server that communicates with various client applications.

IV. Rules for RESTful API URI design

The generic URI syntax:

URI = schema”://”authority”/”path[“?”query][“#”fragment]

A trailing forward slash (/) should not be included in URIs
As the last character of an API path, a forward slash (/) should not be added to avoid confuse. It’s better to drop it from the URI.

/api/v1/users			<---> Good
Good/api/v1/users/		<---> Bad

Forward slash separator (/) must be used to indicate a hierarchical relationship
The forward-slash (/) character is used in the path portion of the URI to indicate a hierarchical relationship between resources.

/products/123/purchase-orders

Hyphens (-) should be used to improve the readability of URIs
Using hyphens (-) to improve the readability of the long English name in path segment.

/api/v1/purchase-orders

Underscores (_) should not be used in URIs
In some case, An underline URL with underscores look like white space to avoid confuse with space white, use hyphens (-) instead of underscores (_).

Lowercase letters should be preferred in URI paths
A mix of upper-case and lower-case letters can make URLs messy and hard to read.
Should make all letters lowercase to help an SEO-friendly URL.

File extensions should not be included in URIs
API should not include artificial file extensions in URIs to indicate the format of a message’s entity body because the end-user doesn't care how the page was generated, because all languages serving a webpage output the same HTML, CSS, and the like, and the user is just viewing the page in their web browser.
Exception case, URI include file extension because they are intended to be saved to the end-user's computer.

/api/v1/projects/123/student	<---> Display student list on UI
/api/v1/projects/123/readme.md	<---> Storing file to end-user's local device

Should the endpoint name be singular or plural?
Avoid mixing singular and plural nouns. Should be use plural nouns is preferred unless the resource is clearly a singular concept

/api/v1/products	<---> Good
/api/v1/product		<---> Bad
/api/v1/profile		<---> Good

V. HTTP Methods

The table below lists the standard methods that have a well-defined meaning for all resources and collections.

METHOD SCOPE SEMATIC
GET resource/collection Retrieve a single/all resource
HEAD resource/collection Retrieve a single/all resource
POST collection Create a new resource in a collection
PUT collection Update a resource
PATH collection Update a resource
DELETE collection Delete a resource
OPTIONS any Return available HTTP methods and other options
GET	/products	<---> Get all products
GET	/products/123	<---> Get product id 123
POST	/products	<---> Create a new product	 (Note: Need to data body)
PUT	/products/123	<---> Update product id 123 (Note: Need to data body)
DELETE	/products/123	<---> Delete product id 123

VI. HTTP response status codes

The table below is standard response status codes that are most populated for an API.

CODE DESCRIPTION METHOD
200 Ok The request has succeeded ALL
201 Created The resource had created and body is empty POST
204 No Content Sending acknowledgment to the client-side after the request is successfully accepted. POST, PUT, PATH, DELETE
400 Bad Request The request is unprocessed, the server-side does not understand what the client-side is asking for. POST, PUT, PATH
401 Unauthorized The request is not allowed to access resources ALL
403 Forbidden The request is not allowed to access resources for any reason. ALL
404 Not Found The request resource is not available GET, PUT, PATH, DELETE

In summary, few categories for the standard codes:

Success			(Starting with numeric 2, 2xx)
Redirection		(Starting with numeric 3, 3xx)
Client Error		(Starting with numeric 4, 4xx)
Server Error		(Starting with numeric 5, 5xx)

VII. Sub and nested resources

Why should we use a nested resource?

Because one resource can be belongs to another resource. So, we should use nest resources to improve readability and easier understand.

You should avoid nesting that is more than 2 levels deep as this can make difficult for the user of API. Sometimes a depth of three is also okay.

For example, the address we are requesting belongs to a specific user. So, the endpoint such as below that can debug easier and it is a one-to-many relationship.

/users/123/address

VIII. Other useful operation

Query parameters is used to filter, sort or collect resource,... that is requesting from client side. It passed in the URL as query string in key-value form.

Query parameter example:

/products?limit=10		<---> Retrieve next 10 resources collections
/products?page=1		<---> To handle pagination logic in server-side
/products?select=name,cost	<---> Fields are responded to client-side
/products?populate=categories	<---> Getting nested collection
/products?sort_fields=name	<---> Filed is sorted
/products?sort=asc		<---> Default sort will be ASC
/products?select=name,code&populate=categories.name&limit=10&page=1&sort_fields=name&sort=asc&cost[lte]=500000

IX. The API version

The API version is arguably the most important part of the API design because the response/request data of a API will be changed constantly after releasing to production. So that users of the API will be impacted by the current service. To avoid breaking the existing service by new changes, the API needs to be upgraded to the new version.

Below is some best practice for API version:

/api/v1/products		<---> The first version
/api/v2/products		<---> The new feature
/api/v2.0.1/products		<---> Fixed bugs for the new feature

Thanks you for reading!!!

Document references

https://www.moesif.com/blog/api-guide/api-design-guidelines

https://medium.com/@dilankam/restful-api-design-best-practices-principles-ded471f573f3