Add API, migration, and browser verification skills
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
---
|
||||
name: api-contract-design
|
||||
description: Use when designing or changing a REST, GraphQL, RPC, module, component, or service interface. Defines stable contracts, predictable errors, boundary validation, compatibility rules, and contract verification before implementation.
|
||||
license: MIT
|
||||
source: adapted from https://github.com/addyosmani/agent-skills/tree/main/skills/api-and-interface-design (MIT)
|
||||
---
|
||||
|
||||
# API Contract Design
|
||||
|
||||
Design the contract before its implementation. Treat every observable public
|
||||
behavior as something a consumer may depend on, including error shapes,
|
||||
ordering, nullability, defaults, and timing-related semantics.
|
||||
|
||||
## Start from consumers and invariants
|
||||
|
||||
1. Identify every consumer and trust boundary.
|
||||
2. Write representative requests/calls and exact successful and failing
|
||||
responses.
|
||||
3. State invariants: identity, authorization, idempotency, ordering,
|
||||
pagination, concurrency, nullability, and retry behavior.
|
||||
4. Define machine-readable input and output schemas before handler code.
|
||||
5. Review the contract for misuse: make valid operations easy and invalid
|
||||
states difficult or impossible to express.
|
||||
|
||||
Do not infer an API shape from its current implementation. Existing quirks may
|
||||
be accidental; record which behaviors are intentional compatibility promises.
|
||||
|
||||
## Keep semantics predictable
|
||||
|
||||
- Use one naming convention across endpoints and fields.
|
||||
- Use one structured error envelope with a stable machine code, safe human
|
||||
message, and optional field details. Never expose stack traces or internals.
|
||||
- Distinguish authentication, authorization, missing resources, validation,
|
||||
conflicts, and server failures consistently.
|
||||
- Validate untrusted input and third-party responses at system boundaries.
|
||||
Once validated, let internal typed code rely on the contract instead of
|
||||
scattering duplicate checks everywhere.
|
||||
- Separate caller-supplied input types from stored/returned resource types.
|
||||
- Paginate every collection that can grow; specify stable ordering, cursor or
|
||||
page semantics, limits, and behavior when data changes between requests.
|
||||
- State whether mutations are idempotent and how clients safely retry them.
|
||||
- For concurrent updates, define conflict handling (version/ETag, transaction,
|
||||
or explicit last-write-wins), rather than leaving races implicit.
|
||||
|
||||
## Evolve additively
|
||||
|
||||
Prefer optional fields, new endpoints, and new enum variants over renaming,
|
||||
removing, or changing types. Before changing an existing interface:
|
||||
|
||||
1. Search all first-party callers, tests, fixtures, generated clients, docs,
|
||||
and telemetry for actual usage.
|
||||
2. Assume unknown external consumers may rely on undocumented observable
|
||||
behavior.
|
||||
3. Classify the change as additive, behavior-changing, or breaking.
|
||||
4. For breaking changes, use a deprecation and migration plan; do not silently
|
||||
maintain two indefinite implementations.
|
||||
|
||||
Be careful when adding enum variants: additions are compatible for producers
|
||||
but can break consumers with exhaustive switches. Document an unknown/fallback
|
||||
policy where independent deployment requires it.
|
||||
|
||||
## Verify the contract
|
||||
|
||||
- Add contract tests for success, each error class, boundary values, and
|
||||
malformed third-party data.
|
||||
- Confirm generated schema/client artifacts match the committed contract.
|
||||
- Test retries and duplicate mutation requests where idempotency is promised.
|
||||
- Test pagination across inserts/deletes and concurrency conflicts.
|
||||
- Compare the implementation's observed responses with the documented schema.
|
||||
- Ensure examples are executable and use the same field/error shapes as the
|
||||
implementation.
|
||||
|
||||
Do not call an interface stable merely because its happy path works. Stability
|
||||
means consumers can predict failures and evolve independently.
|
||||
Reference in New Issue
Block a user