Search results
RESTful API Guidelines
1. OVERVIEW
RESTful APIs started being widely adopted for systems interoperability and integration in the mid-2000s, maybe earlier.
Two decades later, many APIs in production today, that claim to be “RESTful”, violate basic REST principles, creating confusion, frustration, and unnecessary complexity.
Take for instance:
POST /accountSearchByNumber
POST /accountSearchByLogin
POST /DeleteEvent
- Lack of security, either at the protocol level or allowing data access to users/personas not related to it.
- Operation in the request body.
- Inconsistent Resource Naming.
- Often times, level 0 from the Richardson Maturity Model code.
- No documentation.
This blog post is revised regularly to keep the recommendations for building scalable and secure REST APIs up-to-date.
RESTful API Guidelines
2. Naming Resources/URIs
- Nouns to represent resources instead of verbs in the URI
- Plural nouns
- Lowercase
- Hyphens (-) to separate words in the URI
- Nested resources
- Use forward slashes (/) for hierarchy but not trailing forward slash (/)
Do:
/accounts
/accounts/1234
/account-roles
/api/blogs/12/posts
/api/products/100/reviews
Don’t:
/getAccount/1234
/createUser
/accounts/1234/
/account_roles
/AccountRoles
/accountSearchByNumber
/accountSearchByLogin
3. HTTP Methods
-
GET
: Retrieves a resource or collection of resources
Should not change the data/state of resources, idempotent -
POST
: Creates or updates a resource
Not required to be idempotent -
PUT
: Replaces the resource identified by the URI
Idempotent, multiple invocations leave the server in the same state -
DELETE
: Deletes the resource identified by the URI
Idempotent, multiple invocations leave the server in the same state -
PATCH
: Partially updates the resource identified by the URI
Not idempotent -
OPTIONS
: Retrieves available communication options for the resource identified by the URI -
HEAD
: Retrieves metadata without a response body about the resource(s) identified by the URI
headers only, such as size, modification date, etc.
4. Versioning
- URI Versioning
POST /api/v1/accounts
POST /api/v2/accounts
- Header Versioning
Accept: vnd-asimio-tech-provisioning-v1+json
- Custom Header (Capitalize-Case)
Asimio-Tech-Provisioning: 1.0
Industry moving away from the “X-” prefix used to denote non-standard/experimentalHTTP
Headers
5. Path Variables
/accounts/{accountId}
/articles/{articleId}/comments
6. Query Parameters for Filtering, Sorting, Paging, and Field Selection
- Filtering
GET /api/customers?firstName=Blah
GET /api/customers?firstName=Blah&lastName=Meh
GET /api/accounts?role=ROLE1&role=ROLE2
- Paging
GET /api/accounts?page=3&size=2
GET /api/accounts?cursor=abc123&size=2
- Sorting
GET /api/customers?sort=lastName&direction=asc
GET /api/customers?sort=lastName,asc
7. Common HTTP Status Codes
- 2xx group: Successful responses
-
200 OK
: The request succeeded
A resource was retrieved, or an update was successful -
201 CREATED
: A new resource has been created, its URI is in the Location Header -
204 NO CONTENT
: The request was successful, the response has no body
A resource was deleted
-
- 3xx group: Redirection responses
304 NOT MODIFIED
: The response has not been modified, client can continue to use its cached version
- 4xx group: Client error responses
-
404 NOT FOUND
: There is no resource for the requested URI -
400 BAD REQUEST
: The server cannot process the request
Invalid attributes, input out of range, etc., return a list of errors in the response body -
401 UNATHORIZED
: Unauthenticated, the client must authenticate to access the resource(s) represented by the URI -
403 FORBIDDEN
: The client doesn’t have the privileges to access the resource(s) represented by the URI -
405 METHOD NOT ALLOWED
: The server doesn’t support the requested method
A DELETE request for a resource known to the server, a GET request that accepts a JSON-formatted response, but the server produces XML instead
-
- 5xx group: Server error responses
500 INTERNAL SERVER ERROR
: An error the server doesn’t now how to handle or recover from
DB connection issue, etc.
Don’t send the stacktrace as part of the response
8. Authentication and Authorization
- Authentication: Verifies the identity of users or applications accessing the API
- Authorization: Verifies if an authenticated party as the privileges/roles/permissions to access the API
8.1. Common Authentication Schemes:
- Basic
- Digest
- Bearer (Token-based)
- OAuth 2.0
- JWT
- Mutual
8.2. Other (Web)
- Form-based
8.3. Basic Authentication
-
No session management, the user must authenticate with each request.
-
Sequence Flow
-
Web browser’s happy path flow
-
Web
HTTP
Basic Authentication Login popup
-
Web
HTTP
Basic Authentication Success Login page
-
Web
HTTP
Basic Authentication Header
-
-
RESTful API Basic Authentication unhappy path flow
curl -v http://localhost:8080/api/samples
> GET /api/samples HTTP/1.1
...
< HTTP/1.1 401
< WWW-Authenticate: Basic realm="Access to Web and API protected resources via Basic Auth"
...
- RESTful API Basic Authentication happy path flow
curl -v -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" http://localhost:8080/api/samples
GET /api/samples HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
...
HTTP/1.1 200
...
["Sample 1","Sample 2","Sample 3","Sample 4"]
8.4. Digest Authentication
- Uses a nonce token
-
nonce = base64(expirationTime + “:” + md5Hex(expirationTime + “:” + key))
expirationTime: Date and Time when the nonce expires in millis
key: Private key to prevent nonce modification -
Should not be used. Server needs to store the password in plaintext or in MD5 format, considered cryptographically weak nowadays
- Sequence Flow
- RESTful API Digest Authentication unhappy path flow
curl -v http://localhost:8080/api/samples
> GET /api/samples HTTP/1.1
...
< HTTP/1.1 401
< WWW-Authenticate: Digest realm="Access to Web and API protected resources via Digest Auth", qop="auth", nonce="MTc0MzUyMjI5Mzk0MTowNzZlODY0ODBkNmVhMDkwZjhiZWI5NGQxZTgzZmI3Mw=="
...
- RESTful API Digest Authentication happy path flow
curl -v --digest --user username:password http://localhost:8080/api/samples
> GET /api/samples HTTP/1.1
...
< HTTP/1.1 401
< WWW-Authenticate: Digest realm="Access to Web and API protected resources via Digest Auth", qop="auth", nonce="MTc0MzYwNzMyMjkzOTpkYTc0MTY0Y2JhYjE4YjNkYmU4MmZlMjhmNDIyNWU0Nw=="
...
<
* Ignoring the response-body
* Issue another request to this URL: 'http://localhost:8080/api/samples'
* Server auth using Digest with user 'username'
...
> GET /api/samples HTTP/1.1
> Authorization: Digest username="username", realm="Access to Web and API protected resources via Digest Auth", nonce="MTc0MzYwNzMyMjkzOTpkYTc0MTY0Y2JhYjE4YjNkYmU4MmZlMjhmNDIyNWU0Nw==", uri="/api/samples", cnonce="MmI5OTM1M2M1NTRkNjdiNDg5MWIzMzgzMDBjNmZlM2U=", nc=00000001, qop=auth, response="9bb095bf3a1f3ac9f00734eb5ed0e984"
...
< HTTP/1.1 200
...
["Sample 1","Sample 2","Sample 3","Sample 4"]
8.5. API Security
- Adopt Token-based auth like OAuth 2.0, JWT
- Refresh Tokens
- Always use HTTPS (SSL+TLS)
- ACL (Access Control List)
- RBAC (Role-Based Access Control)
Authorization: Api-Key
9. Documentation and Testing Tools
- OpenAPI/Swagger
- Postman, Insomnia
10. Richardson Maturity Model
- HATEOAS: Hypermedia as the Engine of Application State. A REST principle that includes hypermedia links in the response
- HAL: Hypertext Application Language. A format that implements the HATEOAS principle
11. Download RESTful API Guidelines PDF
NEED HELP?
I provide Consulting Services.ABOUT THE AUTHOR
