Web API Design — Agent Skill
Rules from The Design of Web APIs (Arnaud Lauret, Manning 2019). APIs are software's UI for developers — design for consumers, not your database.
Pair with domain-driven-design for bounded contexts; ddia for data/storage; clean-code for handler code.
When to apply
- Designing REST (or REST-like) HTTP APIs
- Reviewing OpenAPI specs, endpoints, error responses
- API versioning, security, documentation
- User says: REST API, OpenAPI, API design, endpoints, web API
Core laws
- Consumer-first — design what callers need to do, not how your DB is shaped.
- Hide implementation — API is a contract; internals can change behind it.
- Straightforward — clear names, types, data; no puzzles.
- Predictable — consistent patterns across the whole API.
- Concise & organized — minimal surface; logical grouping.
- Secure by design — auth, scopes, input validation, least exposure.
- Evolvable — version and extend without breaking consumers.
Agent workflow
1. GOALS CANVAS — whats (user goals), inputs/outputs, all consumer types
2. RESOURCES — nouns, relationships, not DB tables
3. ACTIONS — HTTP methods on resources; idempotency where needed
4. DATA — concepts, responses, parameters (JSON Schema / OAS)
5. USABILITY — straightforward → predictable → concise
6. CONTEXT — security, evolution, network efficiency, docs
Reject provider perspective: don't expose internal IDs, org structure, or ORM shapes without translation.
API goals canvas (Part 1)
For each capability ask:
- What can consumers accomplish? (not how server works)
- Inputs / outputs — data in, data out
- All users — mobile app, partner, internal admin, future consumers
- Missing goals — what consumers need but you haven't listed
Anti-patterns to catch:
- Data model leaked as API (
/users/123/orders/456/line_items/789)
- Business logic steps exposed as chained calls consumers shouldn't orchestrate
- Team boundaries visible in endpoint chaos
REST mapping (Ch 3)
| Concept |
REST expression |
| Resource |
Noun in path (/payments, /customers/{id}) |
| Collection |
Plural path; create via POST to collection |
| Relationship |
Sub-resource or link (/customers/{id}/orders) |
| Action on resource |
HTTP method + path (prefer standard CRUD) |
| Non-CRUD action |
POST to sub-path (/orders/{id}/cancel) sparingly |
HTTP cheat sheet:
- GET — read, safe, idempotent
- POST — create / non-idempotent action
- PUT — full replace, idempotent
- PATCH — partial update
- DELETE — remove, idempotent
Use standard status codes with consistent error body shape.
Data design (Ch 3–4)
- Concepts — stable domain names in JSON (not
fld_usr_nm)
- Responses — ready-to-use; avoid N+1 client assembly when reasonable
- Parameters — clear types/formats (dates, money, enums)
- OpenAPI (OAS) — single source for docs, codegen, review
- Reuse components —
$ref schemas; don't duplicate
Part 2 — Usable API design
Straightforward (Ch 5)
- Crystal-clear names (
createdAt not ts)
- Easy types (ISO-8601 dates, string enums with known values)
- Ready-to-use data in responses — don't make clients join 5 calls
- Exhaustive errors — every failure mode documented and returned consistently
- Informative success feedback (201 + Location, body with id)
Predictable (Ch 6)
- Consistency — same naming, pagination, error format everywhere
- Same concept = same name across endpoints
- Pagination/filter/sort patterns repeated
Concise & organized (Ch 7)
- Don't expose internal/admin fields on public API
- Aggregate goals when consumers always need combined data
- Stateless flows — each request self-contained where possible
Part 3 — Contextual design
Security (Ch 8)
- Authn/authz on every sensitive operation
- Scopes/roles explicit in design
- Never trust client input; validate at boundary
- Don't leak stack traces or internal IDs in errors
Evolution (Ch 9)
- Backward compatible changes preferred (add optional fields)
- Breaking changes → new version or explicit migration path
- Deprecation headers + timeline
- Design for unknown future consumers
Network efficiency (Ch 10)
- Pagination, field selection (
?fields=), compression
- Avoid chatty APIs when batch endpoints are justified
- Caching headers where reads are cacheable
Documentation (Ch 12–13)
- OAS complete: examples, error cases, auth
- Review API designs before build — API design is product design
- Grow APIs deliberately; resist endpoint sprawl
Smells to flag
| Smell |
Fix |
RPC verbs in paths (/getUser, /doPayment) |
Resources + HTTP methods |
| DB tables as endpoints |
Resource model from consumer goals |
| Inconsistent error shapes |
One error schema |
| 200 with error in body |
Proper 4xx/5xx |
| Missing pagination on lists |
Cursor/offset pattern |
| Breaking changes without version |
Version or compat policy |
| Leaking stack traces |
Safe error messages |
| Consumer needs 10 calls for one screen |
Aggregate or expand |
Review output format
## Consumer goals
[What callers need to accomplish]
## Resource model
[Paths, methods, relationships]
## Data & errors
[Schemas, status codes, error consistency]
## Usability
[Straightforward / predictable / concise issues]
## Security & evolution
[Auth, breaking change risks]
## OpenAPI gaps
[Missing docs, examples, components]
Source
Arnaud Lauret, The Design of Web APIs (Manning, 2019).
1---2name: web-api-design3description: Apply Arnaud Lauret's The Design of Web APIs principles when designing, reviewing, or documenting REST/OpenAPI APIs. Use for resources, HTTP methods, error models, versioning, security, consumer-first API design, or when the user mentions REST API, OpenAPI, API design, or Lauret.4---56# Web API Design — Agent Skill78Rules from *The Design of Web APIs* (Arnaud Lauret, Manning 2019). **APIs are software's UI for developers — design for consumers, not your database.**910Pair with **domain-driven-design** for bounded contexts; **ddia** for data/storage; **clean-code** for handler code.1112## When to apply1314- Designing REST (or REST-like) HTTP APIs15- Reviewing OpenAPI specs, endpoints, error responses16- API versioning, security, documentation17- User says: REST API, OpenAPI, API design, endpoints, web API1819---2021## Core laws22231. **Consumer-first** — design what callers need to do, not how your DB is shaped.242. **Hide implementation** — API is a contract; internals can change behind it.253. **Straightforward** — clear names, types, data; no puzzles.264. **Predictable** — consistent patterns across the whole API.275. **Concise & organized** — minimal surface; logical grouping.286. **Secure by design** — auth, scopes, input validation, least exposure.297. **Evolvable** — version and extend without breaking consumers.3031---3233## Agent workflow3435```361. GOALS CANVAS — whats (user goals), inputs/outputs, all consumer types372. RESOURCES — nouns, relationships, not DB tables383. ACTIONS — HTTP methods on resources; idempotency where needed394. DATA — concepts, responses, parameters (JSON Schema / OAS)405. USABILITY — straightforward → predictable → concise416. CONTEXT — security, evolution, network efficiency, docs42```4344**Reject provider perspective:** don't expose internal IDs, org structure, or ORM shapes without translation.4546---4748## API goals canvas (Part 1)4950For each capability ask:51- **What** can consumers accomplish? (not how server works)52- **Inputs / outputs** — data in, data out53- **All users** — mobile app, partner, internal admin, future consumers54- **Missing goals** — what consumers need but you haven't listed5556**Anti-patterns to catch:**57- Data model leaked as API (`/users/123/orders/456/line_items/789`)58- Business logic steps exposed as chained calls consumers shouldn't orchestrate59- Team boundaries visible in endpoint chaos6061---6263## REST mapping (Ch 3)6465| Concept | REST expression |66|---------|-----------------|67| Resource | Noun in path (`/payments`, `/customers/{id}`) |68| Collection | Plural path; create via POST to collection |69| Relationship | Sub-resource or link (`/customers/{id}/orders`) |70| Action on resource | HTTP method + path (prefer standard CRUD) |71| Non-CRUD action | POST to sub-path (`/orders/{id}/cancel`) sparingly |7273**HTTP cheat sheet:**74- GET — read, safe, idempotent75- POST — create / non-idempotent action76- PUT — full replace, idempotent77- PATCH — partial update78- DELETE — remove, idempotent7980Use **standard status codes** with consistent error body shape.8182---8384## Data design (Ch 3–4)8586- **Concepts** — stable domain names in JSON (not `fld_usr_nm`)87- **Responses** — ready-to-use; avoid N+1 client assembly when reasonable88- **Parameters** — clear types/formats (dates, money, enums)89- **OpenAPI (OAS)** — single source for docs, codegen, review90- **Reuse components** — `$ref` schemas; don't duplicate9192---9394## Part 2 — Usable API design9596### Straightforward (Ch 5)97- Crystal-clear names (`createdAt` not `ts`)98- Easy types (ISO-8601 dates, string enums with known values)99- **Ready-to-use data** in responses — don't make clients join 5 calls100- **Exhaustive errors** — every failure mode documented and returned consistently101- Informative success feedback (201 + Location, body with id)102103### Predictable (Ch 6)104- **Consistency** — same naming, pagination, error format everywhere105- Same concept = same name across endpoints106- Pagination/filter/sort patterns repeated107108### Concise & organized (Ch 7)109- Don't expose internal/admin fields on public API110- Aggregate goals when consumers always need combined data111- **Stateless flows** — each request self-contained where possible112113---114115## Part 3 — Contextual design116117### Security (Ch 8)118- Authn/authz on every sensitive operation119- Scopes/roles explicit in design120- Never trust client input; validate at boundary121- Don't leak stack traces or internal IDs in errors122123### Evolution (Ch 9)124- **Backward compatible** changes preferred (add optional fields)125- Breaking changes → new version or explicit migration path126- Deprecation headers + timeline127- Design for unknown future consumers128129### Network efficiency (Ch 10)130- Pagination, field selection (`?fields=`), compression131- Avoid chatty APIs when batch endpoints are justified132- Caching headers where reads are cacheable133134### Documentation (Ch 12–13)135- OAS complete: examples, error cases, auth136- **Review API designs** before build — API design is product design137- Grow APIs deliberately; resist endpoint sprawl138139---140141## Smells to flag142143| Smell | Fix |144|-------|-----|145| RPC verbs in paths (`/getUser`, `/doPayment`) | Resources + HTTP methods |146| DB tables as endpoints | Resource model from consumer goals |147| Inconsistent error shapes | One error schema |148| 200 with error in body | Proper 4xx/5xx |149| Missing pagination on lists | Cursor/offset pattern |150| Breaking changes without version | Version or compat policy |151| Leaking stack traces | Safe error messages |152| Consumer needs 10 calls for one screen | Aggregate or expand |153154---155156## Review output format157158```markdown159## Consumer goals160[What callers need to accomplish]161162## Resource model163[Paths, methods, relationships]164165## Data & errors166[Schemas, status codes, error consistency]167168## Usability169[Straightforward / predictable / concise issues]170171## Security & evolution172[Auth, breaking change risks]173174## OpenAPI gaps175[Missing docs, examples, components]176```177178---179180## Source181182Arnaud Lauret, *The Design of Web APIs* (Manning, 2019).