496303471d
---ci--- project: atelier phase: 7 milestone: v0.1 status: complete phase_role: final milestone_complete: true requirements: covered: [ATELIER-01, ATELIER-02, ATELIER-03, ATELIER-04, ATELIER-05, ATELIER-06, ATELIER-07, ATELIER-08, ATELIER-09, ATELIER-10, ATELIER-11, ATELIER-12, ATELIER-13, ATELIER-14, ATELIER-15, ATELIER-16, ATELIER-17, ATELIER-18, ATELIER-19, ATELIER-20, ATELIER-21, ATELIER-22, ATELIER-23, ATELIER-24, ATELIER-25, ATELIER-26, ATELIER-27, ATELIER-28, ATELIER-29, ATELIER-30, ATELIER-31, ATELIER-32, ATELIER-33, ATELIER-34, ATELIER-35] partial: [] ship: milestone: v0.1 type: NFR tag: v0.0.7 merge: milestone/v0.1-atelier -> main release: https://git.cloudinit.dev/cloudinit-bot/atelier/releases/tag/v0.0.7 ---/ci--- Milestone v0.1 — Initial Framework (NFR, complete). 8 core principles (C1-C8), 11 domains, 110 domain principles, 27 derived docs, 4 good + 3 bad examples, 4 language docs, full matrix, 3 review docs. All 35 requirements covered. 7 patches (v0.0.0 pre-execution through v0.0.7 final). v0.0.7 IS the v0.1.0 milestone release.
68 lines
2.9 KiB
Markdown
68 lines
2.9 KiB
Markdown
# 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 `/OrderItems` or `/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-Key` header) 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.
|
||
- `Link` header or `cursor` field 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. |