> common-api-design
REST API conventions — HTTP semantics, status codes, versioning, pagination, and OpenAPI standards applicable to any framework. (triggers: **/*.controller.ts, **/*.router.ts, **/*.routes.ts, **/routes/**, **/controllers/**, **/handlers/**, rest api, endpoint, http method, status code, versioning, pagination, openapi, api design, api contract)
curl "https://skillshub.wtf/HoangNguyen0403/agent-skills-standard/common-api-design?format=md"Common API Design Standards
Priority: P1 (OPERATIONAL)
Consistent, predictable API contracts reduce integration friction and prevent breaking changes from reaching consumers.
🔧 HTTP Verb Semantics
GETread-only, idempotent — never mutates state.POSTcreate or trigger;PUTfull replace;PATCHpartial update;DELETEremove.- Non-CRUD actions as sub-resources:
POST /orders/:id/cancel.
📡 Status Code Correctness
200success;201created (addLocationheader);204no body.400validation (withdetails[]);401unauthenticated;403unauthorized;404not found.409conflict;422business rule violation;429rate limit (addRetry-After);500unhandled.
📦 URL Design Rules
- Lowercase, kebab-case:
/user-profiles, not/UserProfilesor/user_profiles. - Plural nouns:
/orders,/products. Not/order,/getProducts. - No verbs in paths (except action sub-resources):
/orders/:id/cancel✅,/cancelOrder❌. - Hierarchy: Use nesting only up to 2 levels:
/users/:id/orders✅,/users/:id/orders/:orderId/items/:itemId❌.
🔢 API Versioning
- Strategy: URL path versioning is the default:
/v1/users,/v2/users. - Header versioning (
Api-Version: 2) is acceptable for internal APIs. - Never mix versions in the same controller — each version gets its own route module.
- Support previous major version for minimum 6 months after a new one is released.
- Deprecation: Add
Deprecation: true+Sunset: <date>headers when a version will be retired.
📄 Pagination
- Prefer cursor-based (
cursor+limit) for large/live datasets; offset only for small static ones. - Default
limit: 20, max100. Reject requests exceeding max. - Response envelope:
{ data: [], pagination: { nextCursor, hasNextPage } }.
📝 OpenAPI Contract
- Every API MUST have an OpenAPI 3.1 spec.
- Generate spec from code annotations (not hand-written YAML) to prevent drift.
- Include: request/response schemas, error shapes, auth requirements, examples.
- Review OpenAPI spec as part of PR process — breaking changes require version bump.
🔒 API Security Baseline
- Require auth on all routes by default; use
@Public()or equivalent opt-out. - Validate and sanitize all query params, path params, and request bodies.
- Set
Content-Type: application/jsonexplicitly. Reject unexpected content types. - Include
X-Content-Type-Options: nosniffandX-Frame-Options: DENYheaders.
Anti-Patterns
- No
GETmutations: Search engines and CDNs cache GET — mutating state is catastrophic. - No 200 for errors:
{ "success": false, "data": null }with HTTP 200 breaks monitoring. - No deeply nested URLs: Hard to document, version, and cache.
- No breaking changes without versioning: Removing/renaming fields in-place breaks consumers silently.
> related_skills --same-repo
> typescript-tooling
Development tools, linting, and build config for TypeScript. Use when configuring ESLint, Prettier, Jest, Vitest, tsconfig, or any TS build tooling. (triggers: tsconfig.json, .eslintrc.*, jest.config.*, package.json, eslint, prettier, jest, vitest, build, compile, lint)
> typescript-security
Secure coding practices for TypeScript. Use when validating input, handling auth tokens, sanitizing data, or managing secrets and sensitive configuration. (triggers: **/*.ts, **/*.tsx, validate, sanitize, xss, injection, auth, password, secret, token)
> typescript-language
Modern TypeScript standards for type safety and maintainability. Use when working with types, interfaces, generics, enums, unions, or tsconfig settings. (triggers: **/*.ts, **/*.tsx, tsconfig.json, type, interface, generic, enum, union, intersection, readonly, const, namespace)
> typescript-best-practices
Idiomatic TypeScript patterns for clean, maintainable code. Use when writing or refactoring TypeScript classes, functions, modules, or async logic. (triggers: **/*.ts, **/*.tsx, class, function, module, import, export, async, promise)