Skill: Create REST API Endpoint
Purpose
Produce a consistent, secure, and well-documented HTTP endpoint that satisfies the contract defined in the technical design and passes security review without rework.
When to Use
- Implementing any new HTTP route (GET, POST, PUT, PATCH, DELETE).
- Adding a new resource or action to an existing API.
- Modifying an existing endpoint's contract (request/response shape, auth, or status codes).
Prerequisites
- API contract (path, method, request/response schema) is defined in
docs/architecture/DESIGN-<slug>.md. - Authentication and authorization requirements are specified.
- Error response format is consistent with existing API conventions in TECH.md.
Checklist
Route Definition
- Path naming — use plural nouns for resources (
/users,/orders/{id}), not verbs. - HTTP method — GET (read), POST (create), PUT (full replace), PATCH (partial update), DELETE (remove).
- Route parameters — validate all path and query parameters before use.
Input Validation
- Validate at the boundary — reject invalid input immediately with a
400 Bad Requestand a clear error message. - Use a schema validation library (e.g., Zod, Joi, class-validator) consistent with the project stack.
- Sanitize any user-supplied string that will be rendered or stored.
Authentication & Authorization
- Apply auth middleware to every non-public route.
- Check authorization — verify the caller has permission to access the specific resource (not just a valid token).
- Return
401for unauthenticated requests,403for unauthorized.
Business Logic
- Delegate to a service layer — keep route handlers thin; move logic to a dedicated service or use-case function.
- Handle not-found explicitly — return
404when a requested resource does not exist.
Error Handling
- Never expose stack traces or internal error details to the client.
- Use consistent error response shape:
{ error: string, code?: string }or per project convention. - Log errors with a correlation/trace ID at the appropriate level (WARN or ERROR).
Response
- Return the correct HTTP status:
200(OK),201(Created),204(No Content),400,401,403,404,409(Conflict),422(Unprocessable),500. - Include a
Locationheader for201responses pointing to the created resource. - Keep responses lean — do not over-expose internal model fields; use a response DTO/mapper.
Documentation
- Update or add OpenAPI/Swagger annotations (or equivalent) for the new endpoint.
- Document the error responses — what codes can be returned and why.
Quality Bar
- Endpoint rejects invalid input with a
400before touching the database. - All routes are covered by at least one integration test (happy path + one error path).
- No secrets, internal stack traces, or PII leak in responses.
- Auth middleware is applied and tested.
Common Pitfalls
- Authorization bypass — checking authentication but not resource-level authorization (IDOR).
- Missing input validation — trusting query params or body fields without schema validation.
- Leaking internals — returning raw ORM errors or stack traces to the client.
- Inconsistent error format — mixing error shapes across routes makes client handling harder.
- Fat controllers — putting business logic directly in the route handler; extract to a service.
Source: WojcikMM/spec-development-protocol — distributed by TomeVault.