https://github.com/muath-ye/api-design-best-practice
[English Version] Best practice when you write an API
https://github.com/muath-ye/api-design-best-practice
api laravel muath-ye
Last synced: about 1 year ago
JSON representation
[English Version] Best practice when you write an API
- Host: GitHub
- URL: https://github.com/muath-ye/api-design-best-practice
- Owner: muath-ye
- Created: 2021-02-15T05:06:51.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2021-02-15T18:31:39.000Z (over 5 years ago)
- Last Synced: 2025-04-19T14:57:25.066Z (about 1 year ago)
- Topics: api, laravel, muath-ye
- Homepage:
- Size: 19.5 KB
- Stars: 10
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Best practice when you write an API
## Some of the points to consider while writing an API:
- Write for human.
> Example: ```/users/{id}/card-number``` instead of ```/users/{id}/pin```.
- Should use lower case letters.
> Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/Pending_Orders```.
- Separate words with dashes.
> Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/pending_orders```.
- Follow the naming pattern similar to the folder structure.
- Use Hierarchy.
- Keep in mind while designing an API is maintaining the version number in the API.
- No trailing forward slash.
> Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/pending-orders/``` and both should give the same output.
## Naming
- Resource should be ```nouns``` not ```verbs```.
> Example: /users/{id} instead of /get-user.
- End-points methods should represent their work.
> ```GET /posts``` Retrieves a list of posts.
> ```GET /posts/1``` Retrieves a specific post.
> ```POST /posts``` Create a new post.
> ```PUT /posts/1``` Update all post #1 details.
> ```PATCH /posts/1``` Partially update post #1.
> ```DELETE /posts/1``` Delete post #1.
## Relationships
If there is a relationship between resources it can be represented like the following example:
Suppose that each posts has a comments so the end-points will be in the following form:
> ```GET /posts/1/comments``` Retrieves all comments that related to post number #1.
> ```GET /posts/1/comments/5``` Retrieves comment#5 related to post#1
> ```POST /posts/1/comments``` Create a new comment related in post#1
> ```PUT /posts/1/comments/5``` update comment #5 related in post#1
> ```PATCH /posts/1/comments/5``` Partially updates comment #5 related in post#1
> ```DELETE /posts/1/comments/5``` Delete comment #5 related in post#1
## Always use SSL
To secure your end-points. SSL helps to protect sensitive information such as logins, passwords, account details and cardholders information for e-commerce websites during Internet communication. All data over network will be encrypted.
## Always version your api
Because end-points may be needed to changes or updated so you need to design your end-points with a version that appeared in URL.
## Result filtering, sorting and searching
It’s best to keep the base resource URLs as lean as possible. Complex result filters, sorting requirements, and advanced searching
Use a unique query parameter for each field that implements filter, sorting or searching
### Filtering
if you want to get flight which only opened
> ```/flight?status=open``` so status is a query parameter that implements a filter.
### Sorting
like filtering a generic parameter sort can be used to describe sorting rules.
> ```GET /flights?sort=priority``` - Retrieves a list of flights in descending order of priority.
> ```GET /flights?sort=priority,created_at``` - Retrieves a list of flights in descending order of priority. Within a specific priority, older flights are ordered first.
### Searching
Sometimes basic filters aren’t enough and you need the power of full text search.
This is a combining between filters and sorting.
> ```GET /flight?status=open&sort=priority``` Retrieves a list of opened flights in descending order of priority.
Example of search:
> ```GET /flights?q=return&status=open&sort=priority,created_at``` - Retrieve the highest priority open flights mentioning the word ```return```
## Aliases for common queries
To make the API experience more pleasant for the average consumer, consider packaging up sets of conditions into easily accessible RESTful paths.
Example of alias:
> ```GET /flights/recently_opened```
## Prevent abuse
To prevent abuse you can limit API calls using:
> ```X-Rate-limit``` with status code response
```429 Too Many Requests```
> ```X-Rate-Limit-Limit``` - The number of allowed requests in the current period
> ```X-Rate-Limit-Remaining``` - The number of remaining requests in the current period
> ```X-Rate-Limit-Reset``` - The number of seconds left in the current period.
## Caching
HTTP provides a built-in caching framework! All you have to do is include some additional outbound response headers and do a little validation when you receive some inbound request headers.
There are 2 approaches: ETag and Last-Modified
## Errors
Just like an HTML error page shows a useful error message to a visitor, an API should provide a useful error message in a known consumable format.
API errors typically break down into 2 types: 400 series status codes for client issues & 500 series status codes for server issues.
JSON error body should provide a few things for the developer - a useful error message, a unique error code (that can be looked up for more details in the docs) and possibly a detailed description.
Example:
```json
{
"code" : 1024,
"message" : "Validation Failed",
"errors" : [
{
"code" : 5432,
"field" : "first_name",
"message" : "First name cannot have fancy characters"
},
{
"code" : 5622,
"field" : "password",
"message" : "Password cannot be blank"
}
]
}
```
## HTTP Status code
HTTP response status codes indicate whether a specific HTTP request has been successfully completed.
Responses are grouped in five classes:
- Informational responses (100–199)
- Successful responses (200–299)
- Redirects (300–399)
- Client errors (400–499)
- Server errors (500–599)
The most common responses:
- ```200 OK``` - Response to a successful GET, PUT, PATCH or DELETE. Can also be used for a POST that doesn’t result in a creation.
- ```201 Created``` - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource
- ```204 No Content``` - Response to a successful request that won’t be returning a body (like a DELETE request)
- ```304 Not Modified``` - Used when HTTP caching headers are in play
- ```400 Bad Request``` - The request is malformed, such as if the body does not parse
- ```401 Unauthorized``` - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
- ```403 Forbidden``` - When authentication succeeded but authenticated user doesn’t have access to the resource
- ```404 Not Found``` - When a non-existent resource is requested
- ```405 Method Not Allowed``` - When an HTTP method is being requested that isn’t allowed for the authenticated user
- ```410 Gone``` - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions
- ```415 Unsupported Media Type``` - If incorrect content type was provided as part of the request
- ```422 Unprocessable Entity``` - Used for validation errors
- ```429 Too Many Requests``` - When a request is rejected due to rate limiting