Api design
Role-aware Claude Code plugin: 10 specialist agents (frontend, backend, QA, a11y, perf, security, architect, debugger, code-reviewer, docs), 15 domain commands, 8 skills, and a SQLite-backed learning crystal that compounds your corrections across sessions.
npx -y skills add atuljha23/holocron --skill api-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
REST and GraphQL API design conventions — resource modeling, pagination, error envelopes, versioning, idempotency. Use when adding, changing, or reviewing endpoints.
SKILL.md
2.9 KB, as published. Nobody here has run it
API design
REST
Resource, not action
URLs name nouns. Actions are verbs.
Good: POST /users/:id/password-reset
Bad: POST /resetUserPassword?id=123
Status codes mean things
200success with body201created (includeLocation)204success, no body400client sent something invalid (bad syntax, bad shape)401not authenticated403authenticated but not authorized404resource doesn't exist (or the caller isn't allowed to know it does)409conflict (version conflict, duplicate, precondition failed)422semantic validation failed (body parses but rules reject)429rate limited5xxserver fault — internal detail logged, opaque to caller
Error envelope
Pick one. Use it everywhere.
{
"error": {
"code": "resource_not_found",
"message": "User [email protected] not found.",
"requestId": "abc123"
}
}
codeis machine-readable, stable, lowercase_snake.messageis human-readable. Safe to surface.requestIdlets the caller tell you what went wrong without you reading prod logs.
Pagination
Cursor-based for anything you'll scale. Offset paging breaks under concurrent writes.
GET /messages?cursor=abc&limit=50
→ { items: [...], nextCursor: "xyz" }
Idempotency
Any POST that has side-effects and will be retried needs an idempotency key:
POST /payments
Idempotency-Key: <uuid-v4>
Server stores the (key → response) for a reasonable TTL. Retries return the cached response, not a second charge.
Versioning
Prefer additive changes. Add fields; don't remove or rename. When you must break, version:
- URL (
/v2/...) — simple, explicit, slightly ugly - Accept header (
Accept: application/vnd.foo.v2+json) — prettier URLs, slightly opaque
Pick one per service. Never mix.
GraphQL
Nullability is a contract
String! says "this WILL be present". If you're not sure, it's String (nullable). A lie here cascades.
Relay-style pagination
Connections, edges, pageInfo, cursors. Don't invent your own.
One mutation per intent
updateUser(input: { name, email, password }) is three different operations glued together. Split them.
Errors as types
Return { user: User | UserNotFoundError | ValidationError } unions where it matters. Generic errors[] at the top is for transport-level fault, not business rules.
Across both
- Typed shapes. Schemas (OpenAPI / GraphQL / proto). Generate clients from them.
- Rate limit expensive or abuse-prone endpoints.
- Observability. Every request has a
requestId. Log it. Return it on errors. Tie logs, metrics, and traces together with it. - Auth at the edge — check in the handler or middleware the handler trusts. Never rely on the gateway alone.