OpenAPI 规范基础
OpenAPI 规范(OAS)是一种用于描述 RESTful API 的标准格式。
OpenAPI 规范允许开发者以机器可读的方式定义 API 的结构、参数、响应等信息。
OpenAPI 规范最初被称为 Swagger 规范,后来被捐赠给 OpenAPI Initiative 并更名为 OpenAPI。
OpenAPI 规范的主要作用包括:
- 提供 API 的标准化文档
- 支持 API 的自动化测试
- 生成客户端 SDK
- 促进前后端分离开发
OpenAPI 目前主要有两个广泛使用的版本:
- OpenAPI 2.0(原 Swagger 2.0)
- OpenAPI 3.x(最新稳定版本)
建议新项目使用 OpenAPI 3.x 版本,因为它提供了更多功能和改进。
OpenAPI 规范的结构
OpenAPI 文档通常以 YAML 或 JSON 格式编写。
下面是一个基本的 OpenAPI 文档结构:
实例
info:
title: 示例 API # API 名称
description: 这是一个示例 API 文档
version: 1.0.0 # API 版本
servers:
- url: https://api.example.com/v1 # API 服务器地址
description: 生产环境
- url: https://dev-api.example.com/v1
description: 开发环境
paths: # API 路径定义
/users: # 端点路径
get: # HTTP 方法
summary: 获取所有用户
description: 返回系统中的所有用户列表
operationId: getUsers
tags:
- users # 分组标签
parameters: # 请求参数
- name: limit
in: query
description: 返回结果数量限制
schema:
type: integer
default: 20
responses: # 响应定义
'200': # HTTP 状态码
description: 成功返回用户列表
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'400':
description: 错误的请求参数
components: # 可复用组件
schemas: # 数据模型定义
User:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
email:
type: string
format: email
required:
- id
- name
OpenAPI 核心概念详解
1. 文档元数据 (info)
info 部分包含 API 的基本信息,如标题、描述、版本等:
实例
title: 用户管理 API
description: API 用于管理系统中的用户信息
version: 1.0.0
contact:
name: API 支持团队
email: support@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
2. 服务器信息 (servers)
servers 部分定义可用的 API 服务器列表:
实例
- url: https://api.example.com/v1
description: 生产环境
- url: https://staging-api.example.com/v1
description: 测试环境
3. 路径 (paths)
paths 部分定义 API 的所有端点和它们支持的 HTTP 方法:
实例
/users:
get:
# 获取用户列表
post:
# 创建新用户
/users/{userId}:
get:
# 获取特定用户
put:
# 更新用户
delete:
# 删除用户
4. 操作 (operations)
每个路径下的 HTTP 方法定义了一个 API 操作:
实例
/users/{userId}:
get:
summary: 获取用户详情
description: 根据用户ID获取用户的详细信息
operationId: getUserById
tags:
- users
parameters:
- name: userId
in: path
required: true
description: 用户ID
schema:
type: integer
responses:
'200':
description: 成功获取用户信息
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: 用户不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
5. 参数 (parameters)
参数可以定义在多个位置:
实例
- name: userId
in: path # 路径参数
required: true
schema:
type: integer
- name: filter
in: query # 查询参数
schema:
type: string
- name: X-API-Key
in: header # 请求头参数
schema:
type: string
- name: trace
in: cookie # Cookie参数
schema:
type: string
6. 请求体 (requestBody)
定义 POST、PUT 等方法的请求体:
实例
description: 用户数据
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/UserForm'
7. 响应 (responses)
定义每个操作可能的响应:
实例
'200':
description: 操作成功
content:
application/json:
schema:
$ref: '#/components/schemas/SuccessResponse'
'400':
description: 请求参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
8. 组件 (components)
components 部分用于存储可在整个 API 文档中重用的元素:
实例
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
roles:
type: array
items:
type: string
enum: [admin, user, editor]
required:
- name
Error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/oauth/authorize
scopes:
read: 读取权限
write: 写入权限
9. 数据模型 (schemas)
定义 API 中使用的数据结构:
实例
Product:
type: object
properties:
id:
type: integer
name:
type: string
maxLength: 100
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing]
10. 安全 (security)
定义 API 的认证和授权方法:
实例
- ApiKeyAuth: []
- OAuth2: [read, write]
创建完整的 OpenAPI 文档实例
下面是一个更完整的电子商务 API 示例:
实例
info:
title: 电子商务 API
description: 用于管理在线商店的产品和订单的 API
version: 1.0.0
contact:
name: API 支持团队
email: support@example.com
url: https://api.example.com/support
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.example.com/v1
description: 生产环境
- url: https://dev-api.example.com/v1
description: 开发环境
tags:
- name: products
description: 产品相关操作
- name: orders
description: 订单相关操作
- name: users
description: 用户相关操作
paths:
/products:
get:
summary: 获取产品列表
description: 返回所有可用产品的列表,支持分页和过滤
operationId: getProducts
tags:
- products
parameters:
- name: category
in: query
description: 按产品类别过滤
schema:
type: string
- name: page
in: query
description: 页码
schema:
type: integer
default: 1
- name: limit
in: query
description: 每页数量
schema:
type: integer
default: 20
responses:
'200':
description: 成功获取产品列表
content:
application/json:
schema:
type: object
properties:
total:
type: integer
products:
type: array
items:
$ref: '#/components/schemas/Product'
'400':
description: 参数错误
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
summary: 创建新产品
description: 创建新的产品信息
operationId: createProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: 产品创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: 无效的请求数据
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/products/{productId}:
get:
summary: 获取产品详情
description: 根据ID获取特定产品的详细信息
operationId: getProductById
tags:
- products
parameters:
- name: productId
in: path
required: true
description: 产品ID
schema:
type: integer
responses:
'200':
description: 成功获取产品信息
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
description: 产品不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
put:
summary: 更新产品
description: 更新特定产品的信息
operationId: updateProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
parameters:
- name: productId
in: path
required: true
description: 产品ID
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductUpdate'
responses:
'200':
description: 产品更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: 无效的请求数据
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 产品不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
delete:
summary: 删除产品
description: 删除特定的产品
operationId: deleteProduct
tags:
- products
security:
- ApiKeyAuth: []
- OAuth2: [write]
parameters:
- name: productId
in: path
required: true
description: 产品ID
schema:
type: integer
responses:
'204':
description: 产品删除成功
'401':
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 产品不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/orders:
get:
summary: 获取订单列表
description: 返回所有订单的列表,支持分页和过滤
operationId: getOrders
tags:
- orders
security:
- ApiKeyAuth: []
- OAuth2: [read]
parameters:
- name: status
in: query
description: 按订单状态过滤
schema:
type: string
enum: [pending, processing, shipped, delivered, cancelled]
- name: page
in: query
description: 页码
schema:
type: integer
default: 1
- name: limit
in: query
description: 每页数量
schema:
type: integer
default: 20
responses:
'200':
description: 成功获取订单列表
content:
application/json:
schema:
type: object
properties:
total:
type: integer
orders:
type: array
items:
$ref: '#/components/schemas/Order'
'401':
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
summary: 创建新订单
description: 创建新的订单
operationId: createOrder
tags:
- orders
security:
- ApiKeyAuth: []
- OAuth2: [write]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderCreate'
responses:
'201':
description: 订单创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: 无效的请求数据
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: 未授权
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Product:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
default: true
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
required:
- name
- price
- category
ProductCreate:
type: object
properties:
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
default: true
required:
- name
- price
- category
ProductUpdate:
type: object
properties:
name:
type: string
maxLength: 100
description:
type: string
price:
type: number
format: float
minimum: 0
category:
type: string
enum: [electronics, books, clothing, food]
inStock:
type: boolean
Order:
type: object
properties:
id:
type: integer
format: int64
readOnly: true
userId:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
totalAmount:
type: number
format: float
readOnly: true
status:
type: string
enum: [pending, processing, shipped, delivered, cancelled]
default: pending
shippingAddress:
$ref: '#/components/schemas/Address'
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
required:
- userId
- items
- shippingAddress
OrderCreate:
type: object
properties:
userId:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
shippingAddress:
$ref: '#/components/schemas/Address'
required:
- userId
- items
- shippingAddress
OrderItem:
type: object
properties:
productId:
type: integer
format: int64
quantity:
type: integer
minimum: 1
default: 1
unitPrice:
type: number
format: float
readOnly: true
required:
- productId
- quantity
Address:
type: object
properties:
street:
type: string
city:
type: string
state:
type: string
zipCode:
type: string
country:
type: string
required:
- street
- city
- state
- zipCode
- country
Error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
implicit:
authorizationUrl: https://example.com/oauth/authorize
scopes:
read: 读取权限
write: 写入权限
security:
- ApiKeyAuth: []
OpenAPI 规范的基本语法
OpenAPI 规范支持两种格式:
- YAML(推荐)
- JSON
YAML 格式示例
实例
info:
title: 宠物商店 API
version: 1.0.0
paths:
/pets:
get:
summary: 列出所有宠物
responses:
'200':
description: 成功获取宠物列表
JSON 格式示例
实例
"info": {
"title": "宠物商店 API",
"version": "1.0.0"
},
"paths": {
"/pets": {
"get": {
"summary": "列出所有宠物",
"responses": {
"200": {
"description": "成功获取宠物列表"
}
}
}
}
}
}
如何使用 OpenAPI 规范
1. 创建和编辑 OpenAPI 文档
可以使用以下工具创建和编辑 OpenAPI 文档:
- Swagger Editor:在线编辑器,提供实时预览和验证
- Stoplight Studio:可视化 API 设计工具
- VS Code + OpenAPI 插件:集成开发环境中编辑
2. 文档生成
使用 OpenAPI 规范可以自动生成美观的 API 文档,常用工具包括:
- Swagger UI:生成交互式 API 文档
- ReDoc:提供响应式、可自定义的文档
- Slate:生成优雅的静态文档
3. 代码生成
OpenAPI 可以自动生成多种语言的客户端和服务器代码:
- OpenAPI Generator:支持 40+ 种编程语言
- Swagger Codegen:生成客户端和服务器代码
- NSwag:针对 .NET 生态系统的代码生成器
4. API 测试和模拟
OpenAPI 规范还可用于:
- 自动化测试:使用 Postman、SoapUI 等工具
- API 模拟:Prism、Microcks 等可以基于 OpenAPI 规范模拟 API
最佳实践
1. 设计原则
- 保持端点命名一致
- 使用合适的 HTTP 方法和状态码
- 设计清晰的 URL 路径结构
2. 文档建议
- 提供详细的描述和示例
- 使用标签对 API 进行分组
- 明确指定必填参数
3. 版本控制策略
- 在 URL 中包含版本号(
/v1/users
) - 使用请求头指定版本(
Accept: application/vnd.example.v1+json
) - 在 OpenAPI 文档中明确版本信息
常见问题解答
1. OpenAPI 与 Swagger 的区别?
Swagger 是 OpenAPI 规范的前身。2016 年,Swagger 规范被捐赠给 Linux 基金会并重命名为 OpenAPI 规范。现在,"Swagger" 通常指的是围绕 OpenAPI 规范构建的工具集。
2. OpenAPI 2.0 和 3.x 的主要区别?
OpenAPI 3.x 引入了许多新功能,包括:
- 改进的组件重用
- 更灵活的请求体定义
- 更强大的安全定义
- 改进的 JSON Schema 支持
- links(链接)和 callbacks(回调)支持
3. 如何处理认证和授权?
OpenAPI 支持多种安全机制:
- API 密钥
- HTTP 基本认证
- OAuth2.0
- OpenID Connect
- 自定义头认证
学习资源
- 官方文档:OpenAPI Initiative
- 工具:
- 学习资源:
点我分享笔记