designing-rest-apis
npx machina-cli add skill msewell/agent-stuff/designing-rest-apis --openclawDesigning REST APIs
Workflow: Designing a new API
- Model resources as nouns. Identify domain entities. Use plural nouns for collection URLs (
/orders, not/getOrders). Express relationships with sub-resources, max 2–3 levels deep. - Assign HTTP methods by semantics. GET=read, POST=create, PUT=full replace, PATCH=partial update, DELETE=remove. For non-CRUD actions, use POST with a clear resource name (
POST /orders/7/cancellation). - Define request/response schemas. Use camelCase for JSON fields, UPPER_SNAKE_CASE for enums, RFC 3339 for dates in UTC. Wrap collections in
{ "data": [...] }. Use string type for IDs. Represent money as smallest currency unit + currency code. - Select status codes. Return the most specific code:
201for creation (withLocationheader),204for no-content success,409for conflicts,422for business rule violations. Never return200with an error body. - Design error responses using RFC 9457 (Problem Details). Include
type(URI),title,status,detail. Return all validation errors at once. Never leak stack traces. - Add pagination to every list endpoint. Default: cursor-based pagination. Use offset pagination only for small/static datasets needing jump-to-page. Always include
has_moreor anextlink. - Plan versioning. Use URI path versioning (
/v1/). Only bump for breaking changes. Support at least one prior version with 6–12 month migration window. Signal deprecation viaDeprecationandSunsetheaders. - Address cross-cutting concerns. Add rate limiting headers on every response. Use
Cache-Control+ ETags. Require idempotency keys for POST endpoints with side effects. UseAuthorization: Bearerfor auth. - Write the OpenAPI spec first (design-first, not code-first). Use OpenAPI 3.1. Document every endpoint, every status code, every error type. Lint with Spectral or Redocly CLI.
Workflow: Adopting API-first process
- Identify consumers. List every team and system that will call the API before designing anything. If consumers aren't in the room, the API will be optimized for the producer.
- Run a design session. Start from the consumer's workflow, not the data model. Sketch endpoints and payloads informally before writing YAML. Name disagreements immediately — they're cheap to resolve now, expensive later.
- Write the spec first. Formalize the agreed design as an OpenAPI spec. Review it via PR with automated linting, consumer sign-off, and breaking change detection. Change the spec first, then the implementation — never the reverse.
- Generate mocks immediately. Unblock consumers with a mock server (Prism, Postman Mock Server) the moment the spec is agreed. Consumers build against the mock while the backend builds against the same spec.
- Enforce the contract in CI/CD. Lint specs on every PR. Detect breaking changes before merge. Validate implementation responses against the spec. Run consumer contract tests. Automate all of this — process discipline alone erodes under deadline pressure.
- Govern lightly. Maintain an API catalog tracking each API's lifecycle stage (draft → active → deprecated → retired). Signal deprecation via
DeprecationandSunsetheaders with a migration guide and sunset date. - Design for AI-agent consumers. Write
descriptionfields as if explaining to a non-expert. Provideexamplevalues for every field. Use clearoperationIdvalues. A complete, well-described OpenAPI spec is nearly MCP-compatible for free.
For detailed guidance: references 09–11.
Workflow: Reviewing an existing API
- Check resource modeling. Flag verb-based URLs, deep nesting (>3 levels), inconsistent pluralization, trailing slashes, or file extensions in URLs.
- Check HTTP method usage. Flag GET with side effects, POST used for retrieval, PUT used for partial updates, missing
Locationheader on201responses. - Check error handling. Flag custom error formats (should use RFC 9457),
200with error bodies, leaked internals, one-error-at-a-time validation. - Check pagination. Flag unbounded list endpoints, offset pagination on large datasets, missing
has_more/nextindicators. - Check security. Verify HTTPS-only, object-level authorization (not just endpoint-level), input validation, rate limiting, CORS whitelist (no
*on authenticated endpoints). - Check naming consistency. Flag mixed casing conventions, nullable booleans (should be enums), integer enum values (should be strings), bare array responses.
- Report findings grouped by severity (breaking issues → best practice violations → suggestions).
Key decisions (defaults with escape hatches)
| Decision | Default | Alternative (when) |
|---|---|---|
| Pagination | Cursor-based | Offset — small/static data needing page numbers |
| Partial update | PATCH with JSON Merge Patch (RFC 7396) | JSON Patch (RFC 6902) — need array ops or conditional updates |
| Versioning | URI path (/v1/) | Content negotiation — per-resource granularity needed |
| Auth | OAuth 2.0 + JWT (RS256, 15–30 min TTL) | API keys — simple server-to-server; mTLS — service mesh |
| Async pattern | 202 Accepted + status polling | Webhooks — server-to-server event-driven |
| Upload method | Multipart form data (1–100 MB) | Presigned URLs — cloud-native; Resumable — >100 MB |
| Error format | RFC 9457 (Problem Details) | — (no alternative; this is the standard) |
| Rate limiting | Token bucket | Sliding window — smoother enforcement |
| JSON casing | camelCase | snake_case — Python/Ruby-centric ecosystem |
Reference material
Consult these for detailed guidance, examples, and tradeoff analysis:
- 01 — Resource & URL design, Statelessness
- 02 — Naming conventions, Schema design, HTTP methods
- 03 — Status codes, Error handling (RFC 9457)
- 04 — Versioning, Pagination, Filtering & sorting
- 05 — Bulk & batch operations, Async & long-running operations
- 06 — File uploads & binary data
- 07 — Security (OWASP Top 10), Authentication & authorization, Rate limiting
- 08 — Caching (ETags, Cache-Control), Idempotency, Content negotiation
- 09 — HATEOAS, OpenAPI documentation, Observability, Testing
- 10 — Evolution & deprecation, API-first process, Governance
- 11 — AI-agent consumers (MCP), Organizational adoption, Tooling reference
Source
git clone https://github.com/msewell/agent-stuff/blob/main/skills/designing-rest-apis/SKILL.mdView on GitHub Overview
This skill guides designing, reviewing, and governing RESTful APIs with resource modeling, URL structure, HTTP methods, and RFC 9457-based error handling. It emphasizes pagination, versioning, security, caching, idempotency, OpenAPI documentation, and API-first processes, including considerations for AI-agent consumers. Use it to design new endpoints, review designs, and enforce API contracts in CI/CD.
How This Skill Works
Start by modeling resources as nouns and using plural collection URLs. Assign HTTP methods by semantics, define request/response schemas, and choose precise status codes. Build RFC 9457 compliant error responses, add pagination to lists, plan versioning, and address cross-cutting concerns like rate limiting, caching, and auth. Write OpenAPI 3.1 specs first, generate mocks, and enforce contracts in CI/CD.
When to Use It
- Designing new REST API endpoints
- Reviewing existing API designs
- Adopting API-first development
- Running API design sessions with stakeholders
- Enforcing API contracts in CI/CD and governing an API program
Quick Start
- Step 1: Model resources as nouns and map URLs (e.g., /orders, /orders/{id})
- Step 2: Write the OpenAPI 3.1 spec first, outlining endpoints, payloads, and errors
- Step 3: Add pagination, RFC 9457 error responses, and enforce with CI/CD mocks and tests
Best Practices
- Model resources as nouns and use plural nouns for collections
- Return specific status codes (201, 204, 409, 422) and use RFC 9457 Problem Details for errors
- Paginate every list endpoint (cursor-based by default) with has_more or next
- Write OpenAPI 3.1 specs first and lint them (e.g., with Spectral)
- Enforce contracts in CI/CD with mocks, tests, and a clear deprecation/versioning plan
Example Use Cases
- Cursor-based pagination on /orders with a has_more indicator
- Idempotent POST workflows using an Idempotency-Key header
- OpenAPI-first design for a new billing or payments API
- Deprecation signaling via Deprecation and Sunset headers during version rollouts
- Designing for AI-agent consumers (MCP) with clear response schemas and stable endpoints
Frequently Asked Questions
Related Skills
creating-c4-diagrams
msewell/agent-stuff
Creates, reviews, and interprets C4 software architecture diagrams (System Context, Container, Component, Dynamic, Deployment). Produces Structurizr DSL or Mermaid diagram code following C4 model best practices. Use when creating architecture diagrams for a system, reviewing existing C4 diagrams for correctness and anti-patterns, generating Structurizr DSL workspaces, producing Mermaid C4 diagrams for READMEs, or using C4 diagrams as context for design decisions, code generation, risk analysis, or onboarding.
arazzo-specification
msewell/agent-stuff
Guides writing, reviewing, and modifying Arazzo workflow specifications (OpenAPI Initiative standard for multi-step API workflows). Use when creating Arazzo documents from scratch, adding steps or workflows to existing specs, reviewing Arazzo files for correctness, or generating API workflow definitions. Covers document structure, runtime expressions, success criteria, control flow, data threading, reusable components, workflow composition, AI agent integration, and validation.
kotlin-functional-programming
msewell/agent-stuff
Guides writing idiomatic, functional-style Kotlin code using built-in language features. Use when asked to write, review, or refactor Kotlin code for immutability, pure functions, sealed types, error handling, collections, coroutines, or functional architecture patterns.
property-based-testing-with-kotest
msewell/agent-stuff
Writes property-based tests using Kotest's kotest-property module. Identifies testable properties, designs generators, and configures PBT for Kotlin/JVM projects. Use when writing property-based tests, creating custom Arb generators, choosing property patterns (roundtrip, invariant, idempotence, oracle), debugging shrunk counterexamples, or integrating PBT into a Kotlin test suite alongside example-based tests.
reducing-coupling
msewell/agent-stuff
Analyzes a codebase scope for coupling issues, diagnoses coupling types using the Connascence framework, and proposes a comprehensive refactoring plan with concrete code changes. Use when asked to find coupling, reduce dependencies, decouple modules, or improve modularity in a codebase.
mermaid-sequence-diagrams
msewell/agent-stuff
Generates, reviews, and fixes Mermaid sequence diagrams following syntax rules and best practices. Use when creating sequence diagrams from system descriptions, reviewing existing Mermaid sequence diagrams for correctness, fixing parse errors, or refactoring large diagrams into focused sub-diagrams. Covers participants, arrows, activations, control flow, notes, styling, and common anti-patterns.