This document outlines best practices for API design, including using proper HTTP methods, accepting and responding with JSON, using kebab-case for URLs, plural names for collections, avoiding verbs in URLs, versioning APIs with ordinal numbers, allowing filtering/sorting/pagination, handling errors gracefully, maintaining documentation, and implementing security practices like authentication, CORS, HTTPS, and rate limiting. It also recommends techniques like returning a minimal set of fields, using relations in URLs for nested resources, caching data to improve performance. The goal is to design APIs that are intuitive, secure, and high performing.
2. What is an API in simple terms?
API stands for Application Programming Interface.
It allows two applications to communicate with one
another to access data.
Image source : https://automatedbuildings.com/news/sep19/articles/cochrane/190822114303cochrane.html
3. How applications communicate with one another
to access data?
Gives clients the power to ask for exactly
what they need and nothing more, makes it
easier to evolve APIs over time, and enables
powerful developer tools.
Today we will focus on REST API
GRAPH QL
4. 1. Use proper HTTP Methods
HTTP methods serve the purpose of explaining CRUD functionality.
1 2 3 4 5
5. 2. Accept and respond with JSON
Always validate the content-type and if you want to go with a default
one use content-type: application/json
6. 3. Use kebab-case for URLs
BAD GOOD
Camel case
1 /generatePageThumbnails
Snake case
2 /generate_page_thumb
nails
Kabab case
3 /generate-page-
thumbnails
7. 4. Use ‘Plural Name’ to point to a collection
BAD GOOD note
Singular name
1 /file
Singular name
2 /File
Plural name
3 /files
More info: https://restfulapi.net/resource-naming/
8. 5. Don’t use `verbs` to explain operation in
resourceful URLs
BAD GOOD note
Function itself explaining
what it’s doing.
1 POST
/updateStory
Function itself explaining
what it’s doing.
2 GET /getStory
HTTP method is explaining
what's it’s doing.
3 GET
/stories/{storyId}
Use proper HTTP method to explain the operation for
resourceful URLs (can be done via CURD)
9. 6. `verbs` can be used for non-resourceful URLs
BAD GOOD note
HTTP method is explaining
what's it’s doing.
1 POST
/notifications/{user
Id}/resend
If the function is not doing any CURD operation than we can use verbs
in our non
-resourceful APIs
10. 7. Use simple `Ordinal Number` to version the API
BAD GOOD note
Ordinal number in api
version
1 /v1/files
Don’t modify the existing APIs if it has major changes.
Always create a version of API because it can be used by external entities (more on
next slide). Change might break their functionality.
Ordinal number in api
version
2 /v2/files
Ordinal number in api
version
3 /v1.1/files
Don’t use word numbers
4 /one/files
Don’t use pure number in
api version
5 /1/files
11. 7.1 Why API Versioning?
https://app.example.com/api/v3.2.3/users
Refer to this article for more information.
12. 9. Allow filtering, sorting, and pagination
Filtering and pagination both increase performance by reducing the usage of server
resources. As more data accumulates in the database, the more important these
features become
/users?lastName=Smith&age=30&sort=-lastName,-createdAt&offset=1&limit=1
{
[
{
"firstName":"John",
"lastName":"Smith",
"age":30
}
],
total:2
}
Where `+` means ascending and `-` means descending. So we sort by users -
lastName in alphabetical order and createdAt from most recent to least recent.
Also URL pram should be
camelCase and JSON property
13. 10. Take fields Query Parameter
The amount of data being returned should also be taken into consideration. Add a
fields parameter to expose only the required fields from your API.
Example:
Only return the id, name, description, and url of the file.
GET /files?fields=id,name,description,url
It also helps to reduce the response size in some cases.
14. 11. Use the Relation in the URL For Nested Resources
The amount of data being returned should also be taken into consideration. Add a
fields parameter to expose only the required fields from your API.
Example:
1. GET /stories/1/files : Get the list of all files from story 1.
2. GET /stories/1/files/2: Get the details of file 2, which belongs to story 1.
3. DELETE /stories/1/files/2 : Should delete file 2, which belongs to story 1.
4. PUT /stories/1/files/2 : should update the file info of 2.
15. 13. Handle errors gracefully and return standard
error codes
To eliminate confusion for API users when an error occurs, we should handle errors
gracefully and return HTTP response codes that indicate what kind of error occurred.
This gives debugger of the API enough information to understand the problem that’s
occurred.
16. 14. Maintain good documentation and Use API
design tools
Having good and detailed documentation results in a great user experience for your
API consumers.
● Improved User Adoption
● Increased Awareness
● Saves Support Time and Costs
● Easier Maintenance
● Versioning is more streamlined
Use API design tools:
17. 15. Use best security practices
1. Don’t Pass Authentication Tokens in URL
GET /files/1/token={token}
Instead, pass them with the header: Authorization: Bearer {token}
1. Handle CORS properly
2. Enforce HTTPS (TLS-encrypted)
3. API Rate limiting
4. Input validations and sanitization (Define an implicit input validation by using
strong types like numbers, booleans, dates, times, or fixed data ranges in API
parameters.)
More on : https://dzone.com/articles/security-best-practices-for-rest-apis
18. 16. Rate limiting (Throttling)
Throttling to prevent your API from being overwhelmed by too many requests. It is
standard practice to add some sort of rate limiting to an API. Return a HTTP status
code 429 for too many requests
RFC 6585 introduced a HTTP status code 429 Too Many Requests to accommodate
this.
Example : Amazon API gateway uses rate limiting while calling lambda function.
19. 17. Cache data to improve performance
We can add caching to return data from the local memory cache instead of querying
the database to get the data every time we want to retrieve some data that users
request.
The good thing about caching is that users can get data faster.
However, the data that users get may be outdated. This may also lead to issues when
debugging in production environments when something goes wrong as we keep
seeing old data. There are many kinds of caching solutions like:
● Redis,
● Memcache
● and more.