Designing RESTful APIs is an art that requires attention to detail, a deep understanding of HTTP, and a commitment to the principles laid out by Roy Fielding. However, many APIs that claim to be RESTful fall short of these principles. In this blog, let’s explore 20 common mistakes and their remedies :
1. Misuse of HTTP Methods
- Non-RESTful:
POST /getSubscription?id=123
- RESTful Remedy:
GET /subscriptions/123
2. Ignoring Caching Opportunities
- Non-RESTful: Responses without
Cache-Control
. - RESTful Remedy: Include
Cache-Control: max-age=3600
in GET responses for subscriptions.
3. Inconsistent Error Handling
- Non-RESTful:
{"error": "It failed"}
- RESTful Remedy:
{"error": {"code": 404, "message": "Subscription not found"}}
with a 404 status code.
4. Lack of Resource Nesting
- Non-RESTful:
/subscriptions
,/users
- RESTful Remedy:
/users/123/subscriptions
to list subscriptions for user 123.
5. Overuse of Query Parameters
- Non-RESTful:
/subscriptions?userId=123
- RESTful Remedy:
/users/123/subscriptions
6. Forgetting Pagination
- Non-RESTful: Returning all subscriptions in one call.
- RESTful Remedy:
/subscriptions?page=1&limit=10
7. Failing to Version the API
- Non-RESTful: Directly modifying the API structure.
- RESTful Remedy:
/v2/subscriptions/123
8. Underutilizing HTTP Headers
- Non-RESTful: Passing API keys as query parameters.
- RESTful Remedy:
Authorization: Bearer <token>
9. Not Supporting Conditional Requests
- Non-RESTful: Ignoring use of
ETag
orLast-Modified
. - RESTful Remedy: Respond with
ETag
header and honorIf-None-Match
requests.
10. Poor Resource Identification
- Non-RESTful: Ambiguous identifiers.
- RESTful Remedy:
/subscriptions/{uuid}
whereuuid
is a unique identifier.
11. Ignoring Idempotency in Non-GET Requests
- Non-RESTful:
POST /subscriptions/123/renew
leading to multiple renewals. - RESTful Remedy:
PUT /subscriptions/123/renewal
to renew idempotently.
12. Not Leveraging HATEOAS
- Non-RESTful:
{ "subscriptionId": "123", "status": "active" }
- RESTful Remedy:
{ "subscriptionId": "123", "status": "active", "_links": { "self": { "href": "/subscriptions/123" }, "cancel": { "href": "/subscriptions/123/cancel" } } }
13. Mixing Singular and Plural Nouns
- Non-RESTful: Inconsistent use of singular and plural in resource paths.
- RESTful Remedy: Consistently use plural nouns for resource names:
/subscriptions
for collection routes and/subscriptions/{id}
for specific entities.
14. Exposing Internal Implementation Details
- Non-RESTful: Revealing database IDs or internal structure through APIs.
- RESTful Remedy: Use abstracted, meaningful identifiers:
/subscriptions/12345
where12345
is an opaque identifier.
15. Not Providing Filtering, Sorting, or Searching Capabilities
- Non-RESTful: Forcing clients to download entire data sets.
- RESTful Remedy: Implement query parameters for server-side operations:
/subscriptions?status=active&sortBy=startDate
16. Lack of Media Type Negotiation
- Non-RESTful: Only supporting
application/json
. - RESTful Remedy: Use the
Accept
header for format requests. Respond toAccept: application/xml
for XML format.
17. Incomplete or Missing Documentation
- Non-RESTful: APIs without comprehensive documentation.
- RESTful Remedy: Provide detailed, up-to-date documentation portal.
18. Not Utilizing PATCH
for Partial Updates
- Non-RESTful: Using
PUT
for all updates. - RESTful Remedy: Implement
PATCH
for partial resource updates.
19. Treating Collections and Individual Resources the Same
- Non-RESTful: Same endpoint for collection and individual resource operations.
- RESTful Remedy: Differentiate endpoints for collections and individual resources:
POST /subscriptions
for creating andGET /subscriptions/123
for fetching.
20. Not Handling Asynchronous Operations Properly
- Non-RESTful: Expecting synchronous completion of long-running tasks.
- RESTful Remedy: Use asynchronous patterns with initial
202 Accepted
responses:POST /subscriptions/123/renew
returns202 Accepted
with aLocation
header for status checks.