Skill708 estrellas del repoactualizado 18d ago
old-coder-api
Design, change, or review an HTTP/JSON API surface — endpoints, request/response shapes, authentication and authorization, pagination, idempotency, rate limits, versioning, and deprecations. Use when adding or modifying an HTTP endpoint, reviewing an OpenAPI spec or HTTP route diff, or deciding whether an HTTP API change breaks consumers. Do not use as a protocol-compatibility checklist for gRPC/protobuf, GraphQL, WebSockets, or other non-HTTP/JSON interfaces.
Instalar en Claude Code
Copiargit clone --depth 1 https://github.com/AmazingAng/old-coder /tmp/old-coder-api && cp -r /tmp/old-coder-api/skills/old-coder-api ~/.claude/skills/old-coder-apiDespués abre una sesión nueva de Claude Code; el skill carga automáticamente.
Definición
SKILL.md
# old-coder-api Inspired by Sean Goedecke, *Everything I know about good API design* (2025-08-24). This skill covers HTTP/JSON contract and operability concerns. Its compatibility rules assume JSON consumers. For gRPC/protobuf, GraphQL, WebSockets, or another protocol, apply the transport-independent principles only alongside that protocol's own compatibility rules. This is not a substitute for a full application-security review. **Good APIs are boring.** For the people who build them, an API is a product. For the people who use them, it is a tool in the way of something else. Every minute a consumer spends thinking about your API instead of their goal is waste. An interesting API is a bad API — or would be a better one if it were less interesting. Two failure modes an agent falls into by default, and this skill exists to stop both: 1. **Inventing.** Producing a clever, bespoke interface where the boring conventional one would do. 2. **Breaking.** Renaming, restructuring, or tightening a field because it reads better now — and silently breaking every downstream caller. **Composition with `old-coder`:** when both skills apply, this skill owns the HTTP/JSON contract while `old-coder` owns workflow order, SPEC approval, the gauntlet, and EVIDENCE. Run Step 0 and the gates before SPEC approval; put the surviving API constraints and risks into SPEC and verify them through the gauntlet. For review-only work with no implementation, use this skill's review format without manufacturing a development loop. ## Step 0 — establish scope before designing anything Answer these three, out loud, before writing a route: | Question | Why it changes the work | |---|---| | **Public or internal?** Can you ship code for every consumer? | Internal: breaking changes are affordable, complex authentication is fine, non-engineer ergonomics don't matter. Public: none of that holds. | | **Existing surface or greenfield?** | Existing → run `references/breaking-changes.md` **first**; compatibility outranks every improvement below. | | **Does the product's resource model support this API?** | API design tracks the product's basic resources. If the resources are awkward (state machines with no name, records that only exist inside a job, parent/child relations that aren't modeled), the API will be awkward no matter how carefully you design it. Say so instead of papering over it. | **Honesty rule for step 0:** when the ugliness comes from the underlying model, name it and propose the model fix as the real option. A background-job-polling interface bolted onto a read that *should* be a read is how the worst APIs happen — technical constraints that the UI hides get laid bare in the API, forcing consumers to understand far more of your system than they should have to. ## The gates Run every gate. Use **✓** only for a verified pass, **✗ + concrete fix** for a verified failure, **N/A + reason** only when the gate truly does not apply, and **? + reason** when it remains unverified. Never skip silently. ### 1. Boring A competent consumer should be able to guess this endpoint before reading any docs. - Resources are the product's nouns (`/issues`, `/projects`, `/users`), plural, stable. - Standard verbs and status codes, following the established convention of this API. Use `400` for a general client error; use `422` only when the content type and syntax are valid but the contained instructions cannot be processed. Use `404` for missing and `429` for rate-limited. - Standard field names: `id`, `created_at`, `next_page`, `url`. Match the names the rest of *this* API already uses — internal consistency beats external convention when they conflict. - REST + JSON unless there's a reason. An established, internally consistent HTTP RPC surface can also be boring; do not rename it to resource paths for REST purity. Don't relitigate HATEOAS or JSON-vs-anything; it isn't important. - **Anything surprising needs a written justification line.** If you can't write one, make it boring. ### 2. Don't break userspace Applies only to changes on an existing surface. Full matrix in `references/breaking-changes.md`. - Additive is fine: new endpoints, new optional params, **new response fields**. Consumers are expected to ignore unknown fields. - Removing a field, renaming it, changing its type, moving it (`user.address` → `user.details.address`), narrowing an enum, or tightening validation is a break. Don't, even if it's neater. The HTTP `referer` header is a misspelling and it is still there. - If a break is genuinely unavoidable: versioning, as a **last resort** — see the reference. ### 3. Authentication: make the simplest safe path easy Many server-to-server integrations start life as a `curl` or a 20-line script. For developer-facing server-to-server APIs, default to simple, scoped, revocable API keys. - Use OAuth or another short-lived or sender-constrained flow instead for browser/mobile clients, user-delegated access, high-sensitivity data, or environments where policy requires it. Do not ship long-lived bearer credentials into those clients. - For every credential type, define scope, rotation, revocation, secure transport, and a way to identify or disable the credential during an incident. - N/A for internal credential ergonomics: use the mechanism the infrastructure already provides (mTLS, workload identity, service tokens), while still verifying its operational controls. ### 4. Authorization: enforce who may do what to which resource Authentication identifies a caller; it does not authorize an action. For every endpoint, identify the actor, action, resource, and tenant boundary. - Enforce authorization server-side on the resolved resource. Do not trust a caller-supplied `tenant_id`, owner ID, role, or scope without checking it against the authenticated principal. - Apply the same checks to list, search, bulk, export, nested-resource, and indirect lookup paths; filtering after fetching is not an authorization boundary. - N/A