DEV Community

Cover image for Rest API Design Guide
Caio Cesar
Caio Cesar

Posted on • Updated on

Rest API Design Guide

Design Principles of Rest API's

When designing for API's one must make sure the API can be independent of the client. Also API's might need to evolve without breaking existing implementations. To help navigate this, learning about standards can be beneficial when designing new API's.

This guide contains some basic design guides that can be considered for Restful HTTP API design. The Representational State Transfer (REST) is a way design web services. It is independent of HTTP protocol but we will consider the HTTP protocol in this post.

URI Based

An API resource is identified through an URI for example:

https://domain.com/items/10
Enter fullscreen mode Exit fullscreen mode

Response Types

Consumers of API's frequently exchange information through represented data. One of the most common approaches for exchanging data is the use of JSON, such as the following example:

{"name":"Caio", "id":1, "value":10}
Enter fullscreen mode Exit fullscreen mode

Operation Verbs

REST API's makes use of a standard interface for client server communication the most common operations are:

  • GET- Should only retrieve data.
  • POST- Generally used to create new resources.
  • PUT- Generally used to fully update a resources.
  • PATCH- Applies partial modifications to a resource.
  • DELETE- Deletes the specified resource.

URI Naming Convention

Resource URIs should be based on plural nouns (the resource) and not verbs (the operations on the resource).

HTTP Media Types Semantics

For HTTP Requests formats are defined through the use of media types, also called MIME types. The most common media types are JSON(media type = application/json) and XML(media type = application/xml) formats. The following has an example of a POST request with the JSON media type:

POST https://domain.com/items HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 80
{"name":"Caio", "id":2, "value":100}
Enter fullscreen mode Exit fullscreen mode

If the media type is not supported the server returns the status code 415 (Unsupported Media Type).

A request can have the Accept header defined with the supported media types as displayed in the following sample:

GET https://domain.com/items/1 HTTP/1.1
Accept: application/xml
Enter fullscreen mode Exit fullscreen mode

If the request does match the accepted media types the server returns the status code 406 (Not Acceptable).

Typical Status Codes

The following table displays the most typical list status codes of success and failures to the most common verbs:

Verbs Success Partial Success Failure
GET 200(OK) N/A 404 (Not Found)
POST 201 (Created) 200(OK) 204 (No Content)
PUT 201 (Created) 200(OK) OR 204(No Content) 409 (Conflict)
PATCH 201 (Created) N/A 415 (Unsupported Media Type) OR 400 (Bad Request) OR 409 (Conflict)
DELETE 204(No Content) N/A 404 (Not Found)

Data Filtering

To minimize cost of requests it is a good practice to have filters in GET Operations to filter only necessary data. To effectively apply this a good strategy is to use query strings such as the following:

GET https://domain.com/items?minValue=100
Enter fullscreen mode Exit fullscreen mode

Data Pagination

When working with large collection of data it can return a high amount of unnecessary information. Consider limiting the return for these requests. A solution to this is using query strings that limits the max number of items to get and a starting offset into the collection as displayed in the following example:

GET https://domain.com/items?limit=10&offset=50
Enter fullscreen mode Exit fullscreen mode

To help consumers, GET requests that returns paginated information should include metadata that shows the total number of data available for the request. Also set all optional query string parameters to default values:

GET https://domain.com/items?limit=100&offset=0
Enter fullscreen mode Exit fullscreen mode

Versioning

Most API's will need to evolve with time. Static API's are not very common for many business and application needs. Versioning allows new features to be included to API's without breaking existing resources. There are several strategies regarding the versioning of API's.

URI versioning

A new version is added to the URI such as:

GET https://domain.com/v2/items/10
Enter fullscreen mode Exit fullscreen mode

Query string versioning

A parameter in a query string indicates the version of the API:

GET https://domain.com/items/10?version=2
Enter fullscreen mode Exit fullscreen mode

Header versioning

A custom header will contain the version of the API:

HTTP
GET https://domain.com/items/10 HTTP/1.1
Custom-Header: api-version=2
Enter fullscreen mode Exit fullscreen mode

Conclusion

There many other considerations to API design that are not covered here such as:

  • Caching
  • HATEOAS
  • Partial Responses
  • Open API Initiative

Therefore seeking a deeper understanding to protocols and standards is a good practice to fully comprehend design principles. For every project there might be a different approach to designing an API based on resources available and necessity. It is highly recommended to have a least a basic design strategy when structuring new or existing API's.

References

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
  2. https://azure.microsoft.com/en-us/services/api-management/#overview

Discussion (2)

Collapse
arlemi profile image
Arlemi

That's a great overview. 🙌
What would be your recommendation when it comes to versioning? I feel like I see mostly URI versioning out there.

Collapse
caiocesar profile image
Caio Cesar Author

It depends on necessity for example if changes are constant, and the API evolves frequently it might not be that practical to use URI versioning since it depends on the server routing the request to the appropriate endpoint. To reduce the difference number of URI query string or custom header versioning can be an alternative solution.