Rename kit/ to rules/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
91
rules/patterns/go-api/contract.md
Normal file
91
rules/patterns/go-api/contract.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Contract: REST API Conventions (Go Web Applications)
|
||||
|
||||
## URL Naming
|
||||
|
||||
- Resources are plural nouns: `/api/assets`, `/api/components`, `/api/pricelists`.
|
||||
- Nested resources use parent path: `/api/assets/:id/components`.
|
||||
- Actions that are not CRUD use a verb suffix: `/api/pricelists/:id/export-csv`,
|
||||
`/api/tasks/:id/cancel`, `/api/sync/push`.
|
||||
- No verbs in resource paths: use `/api/assets` + DELETE, not `/api/delete-asset`.
|
||||
|
||||
## HTTP Methods and Status Codes
|
||||
|
||||
| Operation | Method | Success | Notes |
|
||||
|-----------|--------|---------|-------|
|
||||
| List | GET | 200 | |
|
||||
| Get one | GET | 200 / 404 | |
|
||||
| Create | POST | 201 | Return created resource |
|
||||
| Update | PUT / PATCH | 200 | Return updated resource |
|
||||
| Delete / Archive | DELETE | 200 or 204 | |
|
||||
| Async action | POST | 202 | Return `{task_id}` |
|
||||
| Validation error | POST/PUT | 422 | Return field errors |
|
||||
| Server error | any | 500 | Log full error server-side |
|
||||
| Not found | any | 404 | |
|
||||
| Unauthorized | any | 401 | |
|
||||
|
||||
- Never return `200 OK` for validation errors — use `422 Unprocessable Entity`.
|
||||
- Never return `200 OK` with `{"error": "..."}` in the body — use the correct status code.
|
||||
|
||||
## Error Response Format
|
||||
|
||||
All non-2xx responses return a consistent JSON body:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "human-readable message",
|
||||
"fields": {
|
||||
"serial_number": "Serial number is required",
|
||||
"price": "Must be greater than 0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `error` — always present, describes what went wrong.
|
||||
- `fields` — optional, present only for validation errors (422). Keys match form field names.
|
||||
- Never expose raw Go error strings, stack traces, or SQL errors to the client.
|
||||
|
||||
## List Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [...],
|
||||
"total_count": 342,
|
||||
"page": 2,
|
||||
"per_page": 50,
|
||||
"total_pages": 7
|
||||
}
|
||||
```
|
||||
|
||||
- Always include pagination metadata even if the client did not request it.
|
||||
- `items` is always an array — never `null`, use `[]` for empty.
|
||||
|
||||
## Request Conventions
|
||||
|
||||
- Accept `application/json` for API endpoints.
|
||||
- HTML form submissions (htmx) use `application/x-www-form-urlencoded` or `multipart/form-data`.
|
||||
- File uploads use `multipart/form-data`.
|
||||
- Query parameters for filtering and pagination: `?page=1&per_page=50&search=abc&status=active`.
|
||||
|
||||
## Health and Utility Endpoints
|
||||
|
||||
Every application must expose:
|
||||
|
||||
```
|
||||
GET /health → 200 {"status": "ok"}
|
||||
GET /api/db-status → 200 {"ok": true} or 500 {"ok": false, "error": "..."}
|
||||
```
|
||||
|
||||
- `/health` must respond even if DB is down (for load balancer probes).
|
||||
- `/api/db-status` checks the actual DB connection and returns its state.
|
||||
|
||||
## Async Actions
|
||||
|
||||
For long-running operations return immediately with a task reference:
|
||||
|
||||
```
|
||||
POST /api/pricelists/create → 202 {"task_id": "abc123"}
|
||||
GET /api/tasks/abc123 → 200 {"status": "running", "progress": 42, "message": "Processing..."}
|
||||
GET /api/tasks/abc123 → 200 {"status": "success", "result": {...}}
|
||||
```
|
||||
|
||||
See `go-background-tasks/contract.md` for full task contract.
|
||||
Reference in New Issue
Block a user