api-design-patterns

Build APIs that developers love to use.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "api-design-patterns" with this command: npx skills add 4444j99/a-i--skills/4444j99-a-i-skills-api-design-patterns

API Design Patterns

Build APIs that developers love to use.

Design Principles

The Three Laws of API Design

  • Predictable: Consistent patterns throughout

  • Discoverable: Self-documenting, intuitive naming

  • Evolvable: Can change without breaking clients

API-First Mindset

Design → Document → Mock → Build → Test → Deploy

NOT: Build → Document (maybe) → Hope it works

REST Patterns

Resource Naming

Collection

GET /users # List users POST /users # Create user

Item

GET /users/{id} # Get user PUT /users/{id} # Replace user PATCH /users/{id} # Update user DELETE /users/{id} # Delete user

Nested resources

GET /users/{id}/posts # User's posts POST /users/{id}/posts # Create post for user

Actions (when CRUD doesn't fit)

POST /users/{id}/activate POST /orders/{id}/cancel

Naming Conventions

Do Don't

/users

/getUsers , /user-list

/users/{id}

/users/get/{id}

/users/{id}/posts

/getUserPosts

Plural nouns Verbs in URLs

Lowercase, hyphens camelCase, underscores

HTTP Methods

Method Purpose Idempotent Safe

GET Read Yes Yes

POST Create No No

PUT Replace Yes No

PATCH Update No* No

DELETE Remove Yes No

*PATCH can be idempotent if designed carefully

Status Codes

Code Meaning Use When

200 OK Successful GET, PUT, PATCH

201 Created Successful POST with new resource

204 No Content Successful DELETE

400 Bad Request Invalid input

401 Unauthorized Missing/invalid auth

403 Forbidden Valid auth, no permission

404 Not Found Resource doesn't exist

409 Conflict Duplicate, state conflict

422 Unprocessable Valid syntax, invalid semantics

429 Too Many Requests Rate limited

500 Server Error Unhandled server error

Request/Response Patterns

Request Body

{ "email": "user@example.com", "name": "John Doe", "preferences": { "newsletter": true } }

Response: Single Resource

{ "data": { "id": "usr_123", "type": "user", "attributes": { "email": "user@example.com", "name": "John Doe", "createdAt": "2024-01-15T10:30:00Z" }, "relationships": { "organization": { "id": "org_456", "type": "organization" } } } }

Response: Collection

{ "data": [ { "id": "usr_123", "type": "user", ... }, { "id": "usr_124", "type": "user", ... } ], "meta": { "total": 150, "page": 1, "perPage": 20 }, "links": { "self": "/users?page=1", "next": "/users?page=2", "last": "/users?page=8" } }

Error Response

{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid request parameters", "details": [ { "field": "email", "code": "INVALID_FORMAT", "message": "Must be a valid email address" } ], "requestId": "req_abc123" } }

Pagination Patterns

Offset-Based

GET /users?page=2&perPage=20 GET /users?offset=20&limit=20

Pros: Simple, familiar Cons: Inconsistent with real-time data, slow on large datasets

Cursor-Based

GET /users?cursor=eyJpZCI6MTIzfQ&limit=20

Response:

{ "data": [...], "cursors": { "before": "eyJpZCI6MTAzfQ", "after": "eyJpZCI6MTIzfQ" }, "hasMore": true }

Pros: Consistent, performant Cons: Can't jump to page N

Keyset-Based

GET /users?after_id=123&limit=20

Pros: Very performant Cons: Requires sortable unique field

Filtering, Sorting, Search

Filtering

Simple

GET /users?status=active

Multiple values

GET /users?status=active,pending

Operators

GET /users?created_at[gte]=2024-01-01 GET /users?name[contains]=john

Nested

GET /users?organization.name=Acme

Sorting

Single field

GET /users?sort=createdAt

Descending

GET /users?sort=-createdAt

Multiple fields

GET /users?sort=-createdAt,name

Field Selection

GET /users?fields=id,name,email GET /users?fields[user]=id,name&fields[posts]=title

Search

GET /users?q=john GET /users?search=john+doe

Versioning Strategies

URL Path (Recommended for major versions)

GET /v1/users GET /v2/users

Pros: Explicit, cacheable Cons: URL pollution

Header

GET /users Accept: application/vnd.api+json; version=2

Pros: Clean URLs Cons: Harder to test, less visible

Query Parameter

GET /users?version=2

Pros: Easy to test Cons: Breaks caching, URL pollution

Deprecation Pattern

Deprecation: true Sunset: Sat, 31 Dec 2024 23:59:59 GMT Link: </v2/users>; rel="successor-version"

Authentication Patterns

API Keys

Header

Authorization: Api-Key sk_live_abc123

Query (avoid - logged in URLs)

GET /users?api_key=sk_live_abc123 <!-- allow-secret -->

Bearer Tokens (OAuth2/JWT)

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Signing Requests (AWS-style)

Authorization: HMAC-SHA256 Credential=key/date/region/service, SignedHeaders=host;x-date, Signature=abc123

Rate Limiting

Headers

X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 999 X-RateLimit-Reset: 1640000000 Retry-After: 60

Response (429)

{ "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded", "retryAfter": 60 } }

Strategies

Strategy Description Use Case

Fixed Window X requests per minute Simple limiting

Sliding Window Rolling time window Smoother limiting

Token Bucket Burst allowance Traffic spikes

Leaky Bucket Constant rate Steady throughput

GraphQL Patterns

Schema Design

type User { id: ID! email: String! name: String posts(first: Int, after: String): PostConnection! createdAt: DateTime! }

type Post { id: ID! title: String! content: String! author: User! }

type PostConnection { edges: [PostEdge!]! pageInfo: PageInfo! }

type Query { user(id: ID!): User users(filter: UserFilter, first: Int, after: String): UserConnection! }

type Mutation { createUser(input: CreateUserInput!): CreateUserPayload! updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload! }

Naming Conventions

Element Convention Example

Types PascalCase User , BlogPost

Fields camelCase firstName , createdAt

Arguments camelCase userId , first

Enums SCREAMING_SNAKE USER_STATUS , ACTIVE

Mutations verbNoun createUser , updatePost

Error Handling

{ "data": null, "errors": [ { "message": "User not found", "locations": [{ "line": 2, "column": 3 }], "path": ["user"], "extensions": { "code": "NOT_FOUND", "timestamp": "2024-01-15T10:30:00Z" } } ] }

OpenAPI Documentation

Basic Structure

openapi: 3.0.3 info: title: My API version: 1.0.0 description: API description

servers:

paths: /users: get: summary: List users operationId: listUsers tags: [Users] parameters: - name: page in: query schema: type: integer default: 1 responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/UserList'

components: schemas: User: type: object required: [id, email] properties: id: type: string format: uuid email: type: string format: email

Related Skills

Complementary Skills (Use Together)

  • backend-implementation-patterns - Implement the APIs you design

  • testing-patterns - Test your API endpoints

  • deployment-cicd - Deploy and version your APIs

Alternative Skills (Similar Purpose)

  • mcp-builder - If building MCP servers instead of REST/GraphQL APIs

Prerequisite Skills (Learn First)

  • None required - this is a foundational design skill

References

  • references/openapi-template.md

  • Full OpenAPI template

  • references/error-codes.md

  • Standard error code catalog

  • references/sdk-patterns.md

  • Client SDK design patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

freelance-client-ops

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-repo-curator

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-roadmap-strategist

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

code-refactoring-patterns

No summary provided by upstream source.

Repository SourceNeeds Review