Introduction
Good documentation is crucial for API adoption. OpenAPI (formerly Swagger) provides a standard way to describe your API, enabling auto-generated documentation, SDKs, and client libraries. This guide covers creating and maintaining OpenAPI specs.
OpenAPI Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OpenAPI Benefits โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ ๐ Documentation โ
โ โข Auto-generated interactive docs โ
โ โข Always in sync with code โ
โ โ
โ ๐ Client SDKs โ
โ โข Generate 40+ languages โ
โ โข Type-safe bindings โ
โ โ
โ โ๏ธ Server Stubs โ
โ โข Quick API prototyping โ
โ โข Multiple language support โ
โ โ
โ โ
Validation โ
โ โข Request/response validation โ
โ โข Contract testing โ
โ โ
โ ๐ Security โ
โ โข Auth scheme definitions โ
โ โข OAuth flows โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
OpenAPI Document Structure
Basic Structure
# openapi.yaml
openapi: 3.1.0
info:
title: User Management API
description: API for managing users and permissions
version: 1.0.0
contact:
name: API Support
email: [email protected]
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging.example.com/v1
description: Staging server
paths:
/users:
get:
summary: List all users
operationId: listUsers
tags:
- Users
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
- name: offset
in: query
schema:
type: integer
default: 0
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Users'
components:
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
email:
type: string
format: email
Defining Schemas
Object Schemas
components:
schemas:
User:
type: object
required:
- name
- email
properties:
id:
type: string
format: uuid
description: Unique identifier
name:
type: string
minLength: 1
maxLength: 100
email:
type: string
format: email
role:
type: string
enum: [admin, user, guest]
createdAt:
type: string
format: date-time
Error:
type: object
properties:
code:
type: string
message:
type: string
details:
type: array
items:
type: string
Reusing Schemas
components:
schemas:
# Inheritance with allOf
AdminUser:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
permissions:
type: array
items:
type: string
# Partial schemas (JSON:API style)
UserSummary:
type: object
properties:
id:
type: string
name:
type: string
# Array of users
Users:
type: array
items:
$ref: '#/components/schemas/User'
Documenting Endpoints
GET Endpoint
paths:
/users/{userId}:
get:
summary: Get a user by ID
description: Returns a single user
operationId: getUserById
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: string
format: uuid
description: The user's unique identifier
- name: include
in: query
schema:
type: array
items:
type: string
enum: [posts, comments]
description: Related resources to include
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
POST Endpoint
paths:
/users:
post:
summary: Create a new user
operationId: createUser
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- email
- password
properties:
name:
type: string
email:
type: string
password:
type: string
minLength: 8
role:
type: string
default: user
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Authentication
Security Schemes
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
apiKeyAuth:
type: apiKey
in: header
name: X-API-Key
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes:
read: Read access
write: Write access
security:
- bearerAuth: []
- apiKeyAuth: []
Using Security
paths:
/users:
get:
summary: List users (requires auth)
security:
- bearerAuth: []
- apiKeyAuth: []
# ...
Code Generation
Install OpenAPI Generator
# Install generator
npm install @openapitools/openapi-generator-cli
# Generate TypeScript client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-axios \
-o ./src/api/client
# Generate Python client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g python \
-o ./python_client
# Generate server stubs (Express)
npx openapi-generator-cli generate \
-i openapi.yaml \
-g express-server \
-o ./server
Using Generated Client
// Generated client usage
import { UsersApi, Configuration } from './api/client';
const config = new Configuration({
basePath: 'https://api.example.com',
accessToken: 'your-token',
});
const usersApi = new UsersApi(config);
// Fully typed!
const users = await usersApi.listUsers({ limit: 10 });
console.log(users.data);
Interactive Documentation
Swagger UI
// Express with Swagger UI
import swaggerUi from 'swagger-ui-express';
import swaggerJsdoc from 'swagger-jsdoc';
const specs = swaggerJsdoc({
definition: {
openapi: '3.0.0',
info: { title: 'My API', version: '1.0.0' },
paths: {}, // Your routes
},
apis: ['./routes/*.js'],
});
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));
ReDoc
# Or use ReDoc (alternative)
# npm install redoc express
app.get('/docs', (req, res) => {
res.send(`
<redoc
spec-url='/openapi.yaml'
></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
`);
});
Key Takeaways
- Start with OpenAPI - Design-first approach
- Keep it in sync - Generate from code or vice versa
- Use $ref - Reuse schemas to avoid duplication
- Document everything - Descriptions, examples, notes
- Generate clients - Type-safe SDKs for consumers
Comments