kbwen / api-design
Design or review REST/GraphQL APIs when endpoints or contracts change.
0
SKILL.md4.0 KB
<!-- This is a SCAFFOLD skill -->
API Design
When to Apply
- Classification: feature, architecture-change, hotfix (if touching API endpoints)
- Phase: /implement (design & build), /review (compliance check), /test (contract verification)
- Trigger: Task involves creating, modifying, or deprecating API endpoints
Conventions
Customize after /app-init: Replace these generic conventions with your project's ADR decisions.
Endpoint Naming
- Use nouns for resources, not verbs:
GET /usersnotGET /getUsers - Plural resource names:
/users,/orders,/products - Nested resources for relationships:
/users/:id/orders - Use kebab-case for multi-word paths:
/order-items
HTTP Methods
| Action | Method | Success Status | Idempotent |
|---|---|---|---|
| List | GET | 200 | Yes |
| Get one | GET | 200 | Yes |
| Create | POST | 201 | No |
| Full update | PUT | 200 | Yes |
| Partial update | PATCH | 200 | No |
| Delete | DELETE | 204 | Yes |
Error Response Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": {
"field": "email",
"constraint": "required"
}
}
}Standard Error Codes
| HTTP Status | When | Error Code Pattern |
|---|---|---|
| 400 | Invalid input | VALIDATIONERROR, INVALIDFORMAT |
| 401 | Not authenticated | UNAUTHORIZED |
| 403 | Not permitted | FORBIDDEN |
| 404 | Resource not found | NOT_FOUND |
| 409 | Conflict (duplicate) | CONFLICT, DUPLICATE |
| 422 | Business rule violation | UNPROCESSABLE |
| 429 | Rate limited | RATE_LIMITED |
| 500 | Server error | INTERNAL_ERROR |
Pagination
{
"data": [...],
"pagination": {
"total": 100,
"page": 1,
"per_page": 20,
"has_next": true
}
}Versioning
- URL path versioning:
/api/v1/users - Breaking changes require new version
- Deprecation: add
Sunsetheader with date, keep old version for N months
Input Validation
- Validate at the controller/route level BEFORE business logic
- Return ALL validation errors at once (batch), not one at a time
- Sanitize strings: trim whitespace, escape HTML where applicable
- Enforce max lengths on all string fields
Checklist
During /implement:
- [ ] Every endpoint has input validation
- [ ] Every endpoint returns consistent error format
- [ ] Every endpoint has proper auth check (or explicit
publicannotation) - [ ] Pagination for list endpoints
- [ ] Rate limiting consideration (at least documented in spec)
- [ ] No sensitive data in URL parameters (use body or headers)
- [ ] Request/response examples in spec match implementation
During /review:
- [ ] No N+1 query patterns in list endpoints
- [ ] Proper HTTP status codes (not everything is 200)
- [ ] Idempotency for PUT/DELETE
- [ ] Error messages don't leak internal details (stack traces, SQL, paths)
- [ ] CORS configured per ADR policy
Heading-Scoped Read Note
For phase-entry loading, read only:
When to ApplyChecklist
Load Conventions, Anti-Patterns, and References on full read or cache miss only.
Anti-Patterns
- God endpoint: One endpoint that does everything based on query params. Split into specific endpoints.
- Verb in URL:
POST /createUser→POST /users - Inconsistent naming: Mixing
/userand/products(singular vs plural) - Swallowing errors: Catching exceptions and returning 200 with
{ success: false } - Leaking internals: Returning DB column names directly as API fields without mapping
- Missing 404: Returning empty 200 instead of 404 when resource doesn't exist
- Unbounded lists: List endpoints without pagination or default limits
References
- Project ADR:
docs/adr/ADR-00N-project-architecture.md§ API Design - Security guardrails:
.agent/rules/security_guardrails.md(A01: Access Control, A03: Injection) - Spec template:
.agentcortex/templates/spec-app-feature.md§ API Contract