Introduction
OpenAPI (formerly Swagger) has become the industry standard for documenting REST APIs. It enables automatic documentation generation, client SDK generation, and API testing. However, many teams write OpenAPI specs as an afterthought, resulting in incomplete or inaccurate documentation.
This comprehensive guide covers OpenAPI specification design and implementation.
Core Concepts
OpenAPI
Specification for describing REST APIs in machine-readable format.
Schema
Definition of data structure and validation rules.
Path
API endpoint (e.g., /users/{id}).
Operation
HTTP method on a path (GET, POST, etc.).
Parameter
Input to an operation (query, path, header, body).
Response
Output from an operation.
Component
Reusable schema or parameter definition.
OpenAPI Document Structure
openapi: 3.0.0
info:
title: User API
version: 1.0.0
description: API for managing users
contact:
name: API Support
email: [email protected]
license:
name: MIT
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging-api.example.com/v1
description: Staging server
paths:
/users:
get:
summary: List users
operationId: listUsers
tags:
- Users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: per_page
in: query
schema:
type: integer
default: 20
responses:
'200':
description: List of users
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
'401':
description: Unauthorized
post:
summary: Create user
operationId: createUser
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserCreate'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid input
'401':
description: Unauthorized
/users/{userId}:
get:
summary: Get user
operationId: getUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: integer
responses:
'200':
description: User details
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
put:
summary: Update user
operationId: updateUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserUpdate'
responses:
'200':
description: User updated
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
delete:
summary: Delete user
operationId: deleteUser
tags:
- Users
parameters:
- name: userId
in: path
required: true
schema:
type: integer
responses:
'204':
description: User deleted
'404':
description: User not found
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
email:
type: string
format: email
name:
type: string
created_at:
type: string
format: date-time
required:
- id
- email
- name
- created_at
UserCreate:
type: object
properties:
email:
type: string
format: email
name:
type: string
password:
type: string
format: password
required:
- email
- name
- password
UserUpdate:
type: object
properties:
email:
type: string
format: email
name:
type: string
UserList:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
type: object
properties:
page:
type: integer
per_page:
type: integer
total:
type: integer
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
Code Generation
Generate Python Client
# Using openapi-generator
openapi-generator generate -i openapi.yaml -g python -o ./python-client
# Using datamodel-code-generator
datamodel-code-generator --input openapi.yaml --output models.py
Generated Client Usage
from openapi_client import ApiClient, Configuration
from openapi_client.api.users_api import UsersApi
# Configure API
config = Configuration(host="https://api.example.com/v1")
config.api_key["Authorization"] = "your-token"
# Create API client
api_client = ApiClient(config)
users_api = UsersApi(api_client)
# List users
users = users_api.list_users(page=1, per_page=20)
# Create user
new_user = users_api.create_user(
user_create={
"email": "[email protected]",
"name": "John Doe",
"password": "secure-password"
}
)
# Get user
user = users_api.get_user(user_id=1)
# Update user
updated_user = users_api.update_user(
user_id=1,
user_update={"name": "Jane Doe"}
)
# Delete user
users_api.delete_user(user_id=1)
Generate TypeScript Client
# Using openapi-generator
openapi-generator generate -i openapi.yaml -g typescript-axios -o ./ts-client
Documentation Generation
Swagger UI
from flask import Flask
from flasgger import Swagger
app = Flask(__name__)
swagger = Swagger(app, template_file='openapi.yaml')
# Access at http://localhost:5000/apidocs/
ReDoc
<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<redoc spec-url='openapi.yaml'></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"></script>
</body>
</html>
Best Practices
- Keep Spec Updated: Update spec with code changes
- Use Components: Reuse schemas and parameters
- Document Errors: Document all error responses
- Use Examples: Provide example requests/responses
- Version API: Include version in spec
- Security: Document authentication requirements
- Rate Limiting: Document rate limits
- Pagination: Document pagination parameters
- Filtering: Document filtering options
- Testing: Generate tests from spec
External Resources
OpenAPI
Code Generation
Documentation
Conclusion
OpenAPI specification is essential for modern API development. By maintaining accurate specs, you enable automatic documentation, client generation, and testing.
Start with a clear spec, generate documentation and clients, and keep the spec synchronized with your implementation.
OpenAPI specifications are the foundation of API-first development.
Comments