π API Design β
Designing clean, consistent, and developer-friendly APIs.
REST conventions β
| Action | Method | Endpoint | Response |
|---|---|---|---|
| List | GET | /users | 200 + array |
| Get one | GET | /users/:id | 200 or 404 |
| Create | POST | /users | 201 + created object |
| Update (full) | PUT | /users/:id | 200 + updated object |
| Update (partial) | PATCH | /users/:id | 200 + updated object |
| Delete | DELETE | /users/:id | 204 (no content) |
Naming rules β
- Use nouns, not verbs:
/usersnot/getUsers - Use plural:
/usersnot/user - Use kebab-case:
/user-profilesnot/userProfiles - Nest for relationships:
/users/:id/orders - Max 2 levels of nesting
Status codes β
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Successful read/update |
| 201 | Created | Successful creation |
| 204 | No Content | Successful deletion |
| 400 | Bad Request | Validation error |
| 401 | Unauthorized | Missing/invalid auth |
| 403 | Forbidden | Auth valid but no permission |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate or state conflict |
| 422 | Unprocessable | Valid syntax but semantic error |
| 500 | Server Error | Unexpected failure |
Error response format β
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": [
{ "field": "email", "message": "must not be empty" }
]
}
}Pagination β
GET /users?page=2&limit=20
{
"data": [...],
"meta": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
}
}Versioning β
- URL path:
/api/v1/users(most common) - Header:
Accept: application/vnd.api+json;version=1 - Only version when breaking changes are needed