Rules to develop an API
1. Accept and respond with JSON
REST APIs should accept JSON for request payload and also send responses to JSON. JSON
is the standard for transferring data. So add headers as below
Don't return plain text
Content-Type: application/json
Accept: application/json
At a high-level, verbs map to CRUD operations: GET means Read, POST means Create,
PUT and PATCH mean Update, and DELETE means... well, Delete.
A response's status is specified by its status code: 1xx for information, 2xx for
success, 3xx for redirection, 4xx for client errors and 5xx for server errors.
2. Use nouns instead of verbs in endpoint paths
This because, HTTP verbs GET, PUT, PUT, DELETE, PATCH should be sufficient to
describe the action being performed on the resource. We should use the nouns which
represent the entity that the endpoint that we’re retrieving or manipulating as the
pathname.
GET: /articles/2/
POST: /articles/
3 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 maintainers of the API enough information to understand the problem that’s
occurred. We don’t want errors to bring down our system, so we can leave them
unhandled, which means that the API consumer has to handle them.
400 Bad Request – This means that client-side input fails validation.
401 Unauthorized – This means the user isn’t not authorized to access a
resource. It usually returns when the user isn’t authenticated.
403 Forbidden – This means the user is authenticated, but it’s not allowed to
access a resource.
404 Not Found – This indicates that a resource is not found.
500 Internal server error – This is a generic server error. It probably
shouldn’t be thrown explicitly.
502 Bad Gateway – This indicates an invalid response from an upstream server.
503 Service Unavailable – This indicates that something unexpected happened on
server side (It can be anything like server overload, some parts of the system
failed, etc.).
Validation Errors:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"status": "failure",
"message": "Validation error occured"
"exceptionCode": "E_VALIDATION"
"trace": {
"surname": "This field is required."
}
}
Application Errors:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"status": "failure",
"message": "Data not available"
"exceptionCode": "E_DATA_NOT_AVAILABLE"
"trace": {
"error": "Expected at least two items in list."
}
}
Success response
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "success",
"message": ""
"exceptionCode": "E_NO_ERROR"
"data": {
"userId": 12123,
"userName": "Anand Kumar",
"mobileNumber": "919885109781",
"status": "A"
}
}
Use status codes consistently
GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content
4 Don't nest resources
option 1: it is not clear anymore what kind of resource you're requesting. Is it
authors? Is it articles?
GET: /authors/12/articles/
Option 2: use the querystring to filter the articles resource directly
GET: /articles/?author_id=12
5 Database queries must be out of business logic.
Use model for CRUD operation queries
Atleast moove the DB operations out of the business logic.
JSON token Information
{
"iss": "http://localhost:8000/api/auth/login", // token issuer URL
"iat": 1587957064, // issued date(unix timestamp)
"exp": 1587960664, // token expired date (unix timestamp)
"nbf": 1587957064, // the start time when token is valid from / started (unix
timestamp)
"jti": "rw0NERGU9qjhp09i", // JWT unique identifier. used mainly to prevent
redundant processing.
"sub": 15, // token title (default is user id)
"prv": "1d0a020acf5c4b6c497989df1abf0fbd4e8c8d63" // the hash value of user provider
class. especially added it in getJWTCustomClaims()
"aud": "dfhkjasdhfashdfhaskhfksah" // audience claim OPTIONAL
}