2.9 KiB
2.9 KiB
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 OKfor validation errors — use422 Unprocessable Entity. - Never return
200 OKwith{"error": "..."}in the body — use the correct status code.
Error Response Format
All non-2xx responses return a consistent JSON body:
{
"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
{
"items": [...],
"total_count": 342,
"page": 2,
"per_page": 50,
"total_pages": 7
}
- Always include pagination metadata even if the client did not request it.
itemsis always an array — nevernull, use[]for empty.
Request Conventions
- Accept
application/jsonfor API endpoints. - HTML form submissions (htmx) use
application/x-www-form-urlencodedormultipart/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": "..."}
/healthmust respond even if DB is down (for load balancer probes)./api/db-statuschecks 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.