REST stands for "Representational State Transfer". This is an architectural style. A web API conforming to this style is a REST API.
REST stands on 6 guiding principles, important among them are:
- Client-server: separate backend and frontend.
- Stateless: each http request contains enough data (e.g. auth, session, user data) to understand it without knowing what the previous request was.
- Cacheable
- GET: always
- POST: using http headers
expire
,cache-control
,etag
,last-modified
- PUT, DELETE: never
🧠 Concepts
The following are some important, concise, and simplified REST concepts a good backend dev must be familiarized with.
Resource
REST APIs are modeled as a resource hierarchy - where each node is either a collection, or a single resource. A single resource has some state, or sub-resources.
Example of a stateful resource is the following, where a user resource has data/states:
POST /users/:id
{
id: 4e7d418a70f,
name: 'muhammad',
country: 'earth',
verified: true
}
Example of a resource with sub-resources is the following, where a user has multiple projects, each of which are a resource.
GET /users/:id/projects
content-type: application/json
[
{
id: 'postman cli',
desc: 'postman implemented in command-line'
url: 'github.com/midnqp/postman-cli'
},
{
id: 'typescript',
desc: 'typescript is a superset of javascript',
url: 'github.com/microsoft/typescript'
}
]
Idempotency
API Idempotency means "a client can make a request multiple times, returning same response - without having any side-effect".
Making the following requests multiple times produces the same result, and has no further side-effect - thus are "idempotent" APIs:
-
GET /users/:id
- just retrieving same user data -
PUT /users
- just updating same json data -
DELETE /users/:id
- just deleteing the same user
A non-idempotent API:
-
POST /users/:id
- because a new user will be created everytime this request is made
🎨 Designs
Some constraints in REST API naming ensures a design of scalable API endpoints:
- Use plural nouns, e.g. users, orders, categories.
- Use hyphen, not underscores. Use lowercase, never camel-case, e.g.
GET /food-categories
, notGET /foodCategories
. -
Never use CRUD function names, e.g.
GET /users/list
orPOST /users/create
.
Some perfect API endpoints:
-
GET /users
- get a collection/list of users. -
GET /users/:id
- get a single user. -
POST /users/:id
- create a single user. -
PUT /users/:id
- update a single user. -
DELETE /users/:id
- delete a single user.
For sub-resources:
-
GET /users/:id/projects
- get projects of given user -
DELETE /users/:id/projects/:id
- remove a project of given user
Adding some features:
-
GET /users?country=earth&verified=true
- search users bycountry
andverified
-
GET /users?$fields=name,country
- list users, but return only 2 data attributes:name
andcountry
-
GET /users?$sort=name&$order=asc
- list users and sort byname
in ascending order -
GET /users/$page=1&$limit=10
- list users and paginate withpage
andlimit
🚫 Errors
Most Google APIs use resource-oriented API design. Instead of defining different NOT_FOUND
errors, the server uses one standard NOT_FOUND
status code, and tells the client which specific resource was not found.
The smaller error space has advantages:
- reduces the complexity of documentation
- better mapping
- reduces client logic complexity
Model
type Error = {
code: number
message: string
details: any[]
}
-
Error.code
: simple code, easily handled by client -
Error.message
: Developer-facing human-readable error -
Error.details
: Additional error information for client, such as retry info, help link, etc.
Code
- Individual APIs must avoid defining additional error codes.
- Developers must use canonical error codes.
- Standard error codes for Google APIs:
-
200 OK
, not an error; returned on success. -
500 UNKNOWN
, internal server error; unexpected and insufficient info -
400 INVALID_ARGUMENT
, invalid/problematic user data -
404 NOT_FOUND
, something doesn't exist globally, for everyone -
409 ALREADY_EXISTS
, something already exists -
403 PERMISSION_DENIED
, access denied for a user; relevant people have access -
401 UNAUTHENTICATED
, no bearer token; no valid auth creds -
429 RESOURCE_EXHAUSTED
, too many requests; rate-limit exceeded -
400 FAILED_PRECONDITION
, the operation was rejected; business logic unmet -
400 UNAVAILABLE
, the operation was rejected; user should retry
-
Message
Error messages should help users understand & resolve API errors easily.
- Do not assume the user to an expert user of the API.
- Do not assume user knows anything about service implementation.
- Should be constructed such that technical users can respond, and correct it.
- Keep the message brief. If needed, provide a link to more info, questions, feedback. Otherwise, use "details" field.
Top comments (0)