What is OpenAPI?
OpenAPI (formerly Swagger) is a language-agnostic specification for describing REST APIs. A single YAML or JSON file describes your entire API: endpoints, request/response schemas, authentication, and error codes. From this specification you can generate interactive documentation (Swagger UI), client SDKs in 40+ languages, server stubs, and test suites.
OpenAPI 3.0 is the current major version (3.1 is the latest, adding full JSON Schema compatibility). The ecosystem is mature and supported by every major API framework.
Minimal OpenAPI 3.0 Document
openapi: 3.0.3
info:
title: User API
version: 1.0.0
description: Manage users in the system
contact:
name: API Support
email: [email protected]
servers:
- url: https://api.example.com/v1
description: Production
- url: http://localhost:8000/v1
description: Local development
paths:
/users:
get:
summary: List all users
operationId: listUsers
tags: [Users]
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
maximum: 100
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
Schema Components
Define reusable schemas under components/schemas and reference them with $ref:
components:
schemas:
User:
type: object
required: [id, name, email]
properties:
id:
type: integer
format: int64
example: 42
readOnly: true
name:
type: string
minLength: 1
maxLength: 100
example: "Alice Smith"
email:
type: string
format: email
example: "[email protected]"
role:
type: string
enum: [admin, user, viewer]
default: user
createdAt:
type: string
format: date-time
readOnly: true
CreateUserRequest:
type: object
required: [name, email]
properties:
name:
type: string
email:
type: string
format: email
role:
type: string
enum: [admin, user, viewer]
Path Parameters and Request Bodies
paths:
/users/{userId}:
parameters:
- name: userId
in: path
required: true
schema:
type: integer
format: int64
get:
summary: Get a user by ID
operationId: getUser
tags: [Users]
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: Update a user
operationId: updateUser
tags: [Users]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
example:
name: "Alice Updated"
email: "[email protected]"
responses:
'200':
description: Updated user
content:
application/json:
schema:
$ref: '#/components/schemas/User'
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://auth.example.com/oauth/authorize
tokenUrl: https://auth.example.com/oauth/token
scopes:
read: Read access
write: Write access
# Apply globally
security:
- BearerAuth: []
# Or per-operation (overrides global)
paths:
/public/health:
get:
security: [] # No auth required
Reusable Responses and Error Schemas
components:
responses:
BadRequest:
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Error:
type: object
required: [code, message]
properties:
code:
type: string
example: "VALIDATION_ERROR"
message:
type: string
example: "Email is invalid"
details:
type: array
items:
type: object
API-First Development Workflow
Write the OpenAPI spec first, before writing any code:
- Design the spec collaboratively (frontend + backend + product)
- Generate mock servers with Prism or Stoplight — frontend can start building immediately
- Generate server stubs for your language (FastAPI, Express, Spring)
- Implement business logic in the generated stubs
- Generate client SDKs for consumers
- Run contract tests against the spec continuously
# Generate mock server
npx @stoplight/prism-cli mock openapi.yaml
# Generate Python client
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g python \
-o ./client-sdk
# Generate FastAPI server stub
npx @openapitools/openapi-generator-cli generate \
-i openapi.yaml \
-g python-fastapi \
-o ./server
Swagger UI Setup
# FastAPI — automatic OpenAPI + Swagger UI
from fastapi import FastAPI
app = FastAPI(
title="User API",
version="1.0.0",
docs_url="/docs", # Swagger UI
redoc_url="/redoc", # ReDoc alternative
)
# Express.js with swagger-ui-express
const swaggerUi = require('swagger-ui-express');
const spec = require('./openapi.json');
app.use('/docs', swaggerUi.serve, swaggerUi.setup(spec));
Frequently Asked Questions
OpenAPI 3.0 vs 3.1 — which should I use?
OpenAPI 3.1 adds full JSON Schema compatibility and is the recommended choice for new projects. However, tooling support for 3.1 is still catching up. If you rely heavily on code generation tools, check their 3.1 support status first.
Should I write the spec by hand or generate it from code?
For new projects: write the spec first (API-first design). For existing projects: generate from code annotations (FastAPI, Springdoc, NestJS Swagger) and then export to a spec file. Use DevKits OpenAPI Generator Pro to scaffold complete OpenAPI specs from your requirements.
How do I validate request bodies against my OpenAPI schema?
Most frameworks do this automatically (FastAPI, Hapi, express-openapi-validator). For manual validation, use ajv in Node.js or jsonschema in Python. Test your JSON payloads with the DevKits JSON Formatter.