agentsclimarketplace

Api design standards

Skill aethrox/doctrine/skills/api-design-standards

API design discipline grounded in the Microsoft/Google REST guidelines, resource and URL conventions, a chosen versioning strategy, what counts as a backward-compatible vs breaking change, and consumer-driven contract testing. Use when designing a new API endpoint, changing an existing API's request/response shape, deciding how to version an API, or asking whether a change to a public interface is breaking.From its SKILL.md

Install
npx -y skills add aethrox/doctrine --skill api-design-standards

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 18 stars18 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.

SKILL.md

5.7 KB, as published. Nobody here has run it

API Design Standards

An API is a promise to callers you don't control and usually can't see. Adding to that promise is free; changing or removing part of it breaks someone who already depended on it. Every API change is classified against that promise (additive or breaking) before it ships, not discovered after a caller files a bug.

Phase 1: Resource and URL conventions

  • URLs name resources (nouns), never actions (verbs): POST /orders, not POST /createOrder. The HTTP method carries the verb.
  • Collections are plural (/orders), a specific member is the collection plus an identifier (/orders/{id}), and nesting reflects real ownership (/orders/{id}/items), not an arbitrary path someone found convenient.
  • HTTP methods map to a fixed meaning, and only that meaning: GET (read, no side effects, safe to retry and cache), POST (create, or a non-idempotent action), PUT (full replace, idempotent, calling it twice with the same body leaves the same state), PATCH (partial update), DELETE (remove, idempotent).
  • Status codes communicate outcome precisely: 2xx success (201 for created with a Location header, 204 for success with no body), 4xx the caller's fault (400 malformed request, 401 unauthenticated, 403 authenticated but not authorized, 404 not found, 409 conflict, 422 semantically invalid), 5xx the server's fault. Returning 200 with an error payload embedded in the body hides the failure from every generic HTTP-aware tool (retries, caches, monitoring).

Phase 2: Versioning strategy

Pick one signal and use it consistently across the whole API; mixing strategies forces every client to handle more than one:

StrategyHowTradeoff
URI path (/v2/orders)version segment in the pathmost discoverable and cacheable, but encourages whole-API version bumps for a change that only touched one resource
Header / content negotiation (Accept: application/vnd.api+json;version=2)version encoded in a request headermost correct REST semantics (a version is a different representation of the same resource, not a different resource) but far less discoverable: undebuggable by just reading a URL
Query parameter (?version=2)version as a query paramsimplest to add after the fact, easiest to accidentally omit and silently get a default

Version the API only when a breaking change (Phase 3) actually requires it. A version bump for a purely additive change forces every existing client to migrate for no reason; that cost is the same mistake a hand-picked SemVer bump is, applied to an API instead of a package.

Phase 3: What's backward-compatible vs breaking

ChangeCompatible?
Adding a new optional request fieldCompatible: old clients that don't send it are unaffected
Adding a new field to a responseCompatible if clients are expected to ignore unknown fields: state this expectation explicitly in the API's docs, since some client generators fail closed on unknown fields
Adding a new endpointCompatible
Removing or renaming a field, endpoint, or enum valueBreaking
Changing a field's type or meaning (a string that used to be an ID now being a display name)Breaking
Making a previously-optional field requiredBreaking
Changing default behavior for an omitted parameterBreaking
Tightening validation on an existing field (was permissive, now rejects previously-valid values)Breaking

When a breaking change is unavoidable (security fix, correcting a genuinely wrong design): communicate it ahead of the change, support the old and new shape in parallel for a stated deprecation window (see dependency-upgrade-management for the deprecation-signal mechanics), and only remove the old shape after that window closes.

Phase 4: Contract testing

  • An OpenAPI (or equivalent) schema is the API's published, machine-readable shape; validate requests and responses against it in CI so a gross schema violation is caught before it reaches a client.
  • For APIs consumed by services you also control (internal microservices), add consumer-driven contract testing: the consumer writes a test capturing exactly what it expects from the provider, the provider verifies against that captured contract in its own CI. This catches a breaking change (a renamed field, a removed endpoint) at the point the provider would have shipped it, not after deploy, in the consumer's production logs.
  • Run the schema validation and the contract verification as CI gates, not manual pre-release checklist items; a check that depends on someone remembering to run it will eventually not run.

Done when

  • Every endpoint uses resource-noun URLs and the HTTP method matching its actual semantics.
  • The API uses one versioning signal consistently, and a version bump happened only because Phase 3 classified the change as breaking.
  • Every changed field, endpoint, or default was checked against the Phase 3 table before shipping.
  • Any unavoidable breaking change has a stated deprecation window with the old and new shape both live during it.
  • Schema validation and (for internally-consumed APIs) contract tests run as CI gates.
  • Generated prose uses commas, colons, periods, or reworded sentences instead of em dashes.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.