2.9 KiB
2.9 KiB
REST — Derived Rules
Derives from
domains/api/first-principles.md. Applies P1–P10 to REST specifically.
Resource Naming (P2 Clarity, P3 Predictability)
- Nouns, not verbs:
/users,/orders, not/getUsers. - Plural:
/users(collection),/users/{id}(item). - Lowercase, hyphenated:
/order-items, not/OrderItemsor/order_items. - Nesting max 2 levels:
/users/{id}/orders, not/users/{id}/orders/{oid}/items/{iid}.
HTTP Methods (P1 Contract Fidelity, P6 Idempotency)
| Method | Semantics | Idempotent | Safe |
|---|---|---|---|
| GET | Read | Yes | Yes |
| POST | Create | No | No |
| PUT | Replace (full) | Yes | No |
| PATCH | Update (partial) | No | No |
| DELETE | Remove | Yes | No |
- PUT requires the full resource. PATCH requires only the delta. Never accept a partial PUT.
- POST creates; never use POST for read operations. POST is not cacheable.
Status Codes (P9 Error Transparency, P1 Contract Fidelity)
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Successful GET, PUT, PATCH |
| 201 | Created | Successful POST that created a resource |
| 204 | No Content | Successful DELETE, or empty response |
| 400 | Bad Request | Malformed request (client error) |
| 401 | Unauthorized | Authentication required or failed |
| 403 | Forbidden | Authenticated but not permitted |
| 404 | Not Found | Resource does not exist |
| 409 | Conflict | State conflict (e.g., duplicate) |
| 422 | Unprocessable | Well-formed but semantically invalid |
| 429 | Too Many Requests | Rate limited |
| 500 | Internal Error | Server bug — never leak stack trace |
- Never return 200 on an error. Never return 500 with a stack trace.
- 401 vs 403: 401 = "who are you?", 403 = "I know who you are, but you can't."
Idempotency (P6 Idempotency)
- POST: not idempotent. Use an idempotency key (
Idempotency-Keyheader) for safe retry. - PUT: idempotent by definition — same PUT twice = same state.
- DELETE: idempotent — deleting a non-existent resource is success (204).
- PATCH: not idempotent by default; can be made idempotent with explicit versioning.
Pagination (P7 Performance, see pagination.md)
- Default to cursor pagination for collections > 100 items.
- Never return unbounded collections.
Linkheader orcursorfield in response body.
Versioning (P5 Versioning, P10 Stability, see versioning.md)
- Version in the URL (
/v1/users) or in the header (Accept: application/vnd.atelier.v1+json). - Pick one. Be consistent across all endpoints.
- Never make a breaking change without a new version and a deprecation cycle.
Security (P8 Security, see domains/security/)
- HTTPS only. Redirect HTTP to HTTPS.
- Authentication on every non-public endpoint. No opt-in auth.
- Rate limiting on write endpoints (POST, PUT, PATCH, DELETE).
- Validate every input against a schema. Never pass raw request body to the database.