Rest API Design Guide
Tags: api, architecture, cloud, design
Published: 2022-05-31 22:31:19

#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
```

###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:

```json
{"name":"Caio", "id":1, "value":10}
```

###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).

| Verbs| Correct URI| Incorrect URI|
| ---- | ---------- | ------------ |
| GET| https://domain.com/items|https://domain.com/get-item |
| POST| https://domain.com/items|https://domain.com/insert-item|
| PUT| https://domain.com/items|https://domain.com/update-item|
| DELETE| https://domain.com/items|https://domain.com/delete-tiem|

###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}
```

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
```
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
```
###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
```

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
```

###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
```
####Query string versioning
A parameter in a query string indicates the version of the API:
```
GET https://domain.com/items/10?version=2
```
####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
```

#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