// "Design and document RESTful and GraphQL APIs with OpenAPI/Swagger specifications, authentication patterns, versioning strategies, and best practices. Use for: (1) Creating API specifications, (2) Designing REST endpoints, (3) GraphQL schema design, (4) API authentication and authorization, (5) API versioning strategies, (6) Documentation generation"
| name | api-designer |
| description | Design and document RESTful and GraphQL APIs with OpenAPI/Swagger specifications, authentication patterns, versioning strategies, and best practices. Use for: (1) Creating API specifications, (2) Designing REST endpoints, (3) GraphQL schema design, (4) API authentication and authorization, (5) API versioning strategies, (6) Documentation generation |
This skill provides comprehensive guidance for designing, documenting, and implementing modern APIs. It covers both REST and GraphQL paradigms, with emphasis on industry best practices, clear documentation, and maintainable architecture. Use this skill to create production-ready API designs that are scalable, secure, and developer-friendly.
Use this skill when:
Identify core resources (nouns) your API will expose:
Resources: Users, Posts, Comments
Collections:
- GET /users (List all users)
- POST /users (Create new user)
Individual Resources:
- GET /users/{id} (Get specific user)
- PUT /users/{id} (Replace user - full update)
- PATCH /users/{id} (Update user - partial)
- DELETE /users/{id} (Delete user)
Nested Resources:
- GET /users/{id}/posts (Get user's posts)
- POST /users/{id}/posts (Create post for user)
Follow RESTful naming conventions:
Best Practices:
/users, /posts (not /user, /post)/blog-posts (not /blogPosts or /blog_posts)/posts?status=published&author=123Quick Examples:
✅ Good:
GET /users
GET /users/123/posts
GET /posts?published=true&limit=10
❌ Bad:
GET /getUsers
GET /users/123/posts/comments/likes (too deep nesting)
GET /posts/published (use query param instead)
Map operations to standard HTTP methods:
Structure JSON payloads consistently:
Naming Conventions:
usr_, post_createdAt, updatedAtExample Response:
{
"id": "usr_1234567890",
"username": "johndoe",
"email": "john@example.com",
"profile": {
"firstName": "John",
"lastName": "Doe"
},
"createdAt": "2025-10-25T10:30:00Z",
"updatedAt": "2025-10-25T10:30:00Z"
}
Design comprehensive error responses:
Error Response Format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{
"field": "email",
"message": "Email format is invalid"
}
],
"requestId": "req_abc123xyz",
"timestamp": "2025-10-25T10:30:00Z"
}
}
Key Status Codes:
200 OK: Successful GET, PUT, PATCH201 Created: Successful POST204 No Content: Successful DELETE400 Bad Request: Invalid request data401 Unauthorized: Missing/invalid authentication403 Forbidden: Authenticated but not authorized404 Not Found: Resource doesn't exist422 Unprocessable Entity: Validation errors429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server errorCursor-Based Pagination (recommended for large datasets):
GET /posts?limit=20&cursor=eyJpZCI6MTIzfQ
Response:
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTQzfQ",
"hasMore": true
}
}
Offset-Based Pagination (simpler for small datasets):
GET /posts?limit=20&offset=40&sort=-createdAt
Response:
{
"data": [...],
"pagination": {
"total": 500,
"limit": 20,
"offset": 40
}
}
For detailed pagination strategies and filtering patterns, see references/rest_best_practices.md.
Create type definitions for your domain:
type User {
id: ID!
username: String!
email: String!
profile: Profile
posts(limit: Int = 10): [Post!]!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
published: Boolean!
author: User!
tags: [String!]!
createdAt: DateTime!
}
Define read operations with filtering:
type Query {
user(id: ID!): User
post(id: ID!): Post
users(
limit: Int = 10
offset: Int = 0
search: String
): UserConnection!
posts(
limit: Int = 10
published: Boolean
authorId: ID
tags: [String!]
): PostConnection!
}
Define write operations with input types and error handling:
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
createPost(input: CreatePostInput!): CreatePostPayload!
}
input CreateUserInput {
username: String!
email: String!
password: String!
}
type CreateUserPayload {
user: User
errors: [Error!]
}
For complete GraphQL schema examples, see examples/graphql_schema.graphql.
Authorization Code Flow (web apps with backend):
1. Redirect to /oauth/authorize with client_id, redirect_uri, scope
2. User authenticates and grants permission
3. Receive authorization code via redirect
4. Exchange code for access token at /oauth/token
5. Use access token in Authorization header
Client Credentials Flow (service-to-service):
POST /oauth/token
{
"grant_type": "client_credentials",
"client_id": "CLIENT_ID",
"client_secret": "SECRET"
}
PKCE Flow (mobile/SPA - most secure for public clients):
1. Generate code_verifier and code_challenge
2. Request authorization with code_challenge
3. Exchange code for token with code_verifier (no client_secret needed)
Token Structure:
{
"header": { "alg": "RS256", "typ": "JWT" },
"payload": {
"sub": "usr_1234567890",
"iat": 1698336000,
"exp": 1698339600,
"scope": ["read:posts", "write:posts"],
"roles": ["user", "editor"]
}
}
Usage:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
X-API-Key: sk_live_abcdef1234567890
Best Practices:
For comprehensive authentication patterns including refresh tokens, MFA, and security best practices, see references/authentication.md.
/v1/users
/v2/users
Pros: Clear, explicit, easy to cache and route Cons: URL proliferation, multiple codebases
Accept: application/vnd.myapi.v2+json
API-Version: 2
Pros: Clean URLs, same endpoint Cons: Less visible, harder to test in browser
Create new version for:
Don't version for:
For detailed versioning strategies, deprecation processes, and migration patterns, see references/versioning-strategies.md.
openapi: 3.0.0
info:
title: My API
version: 1.0.0
description: API description
servers:
- url: https://api.example.com/v1
paths:
/users:
get:
summary: List users
parameters:
- name: limit
in: query
schema:
type: integer
default: 10
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
components:
schemas:
User:
type: object
required:
- username
- email
properties:
id:
type: string
username:
type: string
email:
type: string
format: email
For complete OpenAPI specification examples, see examples/openapi_spec.yaml.
Use the helper script to generate and validate specs:
# Generate OpenAPI spec from code
python scripts/api_helper.py generate --input api.py --output openapi.yaml
# Validate existing spec
python scripts/api_helper.py validate --spec openapi.yaml
# Generate documentation site
python scripts/api_helper.py docs --spec openapi.yaml --output docs/
GET /health
Response: { "status": "ok", "timestamp": "2025-10-25T10:30:00Z" }
POST /users/batch
{
"operations": [
{ "method": "POST", "path": "/users", "body": {...} },
{ "method": "PATCH", "path": "/users/123", "body": {...} }
]
}
POST /webhooks/configure
{
"url": "https://your-app.com/webhook",
"events": ["user.created", "post.published"],
"secret": "webhook_secret_key"
}
For additional patterns including idempotency, long-running operations, file uploads, and soft deletes, see references/common-patterns.md.
references/rest_best_practices.md - Complete REST API patterns, status codes, and implementation detailsreferences/authentication.md - OAuth 2.0, JWT, API keys, MFA, and security best practicesreferences/versioning-strategies.md - Versioning approaches, deprecation, and migration strategiesreferences/common-patterns.md - Health checks, webhooks, batch operations, and moreexamples/openapi_spec.yaml - Complete OpenAPI 3.0 specification for a blog APIexamples/graphql_schema.graphql - Full GraphQL schema with queries, mutations, and subscriptionsscripts/api_helper.py - API specification generation, validation, and documentation utilities