2. OpenAPI 规范入门:OpenAPI 3.0 核心概念、YAML/JSON 定义、路径与操作、请求/响应模型
OpenAPI 规范(原 Swagger 规范)是描述 RESTful API 的行业标准。OpenAPI 3.0 作为当前主流版本,提供了结构化的接口定义语言,使契约测试、性能调优和故障排查有了统一的契约基础。本节将系统梳理其核心概念与表达方式。
2.1 OpenAPI 3.0 核心概念
OpenAPI 3.0 文档是一个自描述的 API 契约,包含以下核心顶层对象:
| 顶层对象 | 作用 | 必填 |
|---|---|---|
openapi |
声明规范版本号(如 3.0.3) |
是 |
info |
API 元信息:标题、版本、描述 | 是 |
servers |
API 的基础 URL 列表(支持多环境) | 否 |
paths |
所有 API 路径及操作的核心容器 | 是 |
components |
可复用的 schema、参数、响应、请求体 | 否 |
tags |
路径分组标签,用于文档分类 | 否 |
契约测试视角:
paths 和 components 是契约测试的核心验证对象。路径定义操作契约,组件定义数据契约。性能调优时,servers 字段用于切换压测目标环境。
2.2 YAML / JSON 定义方式
OpenAPI 3.0 支持 YAML 和 JSON 两种序列化格式。YAML 因其可读性高、注释友好,成为社区首选;JSON 则更适合程序化生成和传输。
格式对比:
| 特性 | YAML | JSON |
|---|---|---|
| 可读性 | 高(缩进结构、支持注释) | 中(括号密集、无注释) |
| 文件大小 | 较小(无冗余引号/逗号) | 较大 |
| 工具生态 | 需注意缩进陷阱 | 解析严格、兼容性好 |
| 推荐场景 | 手写契约、代码仓库管理 | API 网关、CI/CD 管道 |
YAML 示例(推荐):
openapi: "3.0.3"
info:
title: 订单服务 API
version: "1.0.0"
description: 提供订单创建与查询能力
servers:
- url: https://api.example.com/v1
description: 生产环境
paths:
/orders:
get:
summary: 查询订单列表
operationId: listOrders
parameters:
- name: status
in: query
schema:
type: string
responses:
'200':
description: 成功返回订单列表
content:
application/json:
schema:
$ref: '#/components/schemas/OrderList'
components:
schemas:
Order:
type: object
properties:
id:
type: integer
total:
type: number
format: float
OrderList:
type: array
items:
$ref: '#/components/schemas/Order'
JSON 等价示例:
{
"openapi": "3.0.3",
"info": {
"title": "订单服务 API",
"version": "1.0.0"
},
"paths": {
"/orders": {
"get": {
"operationId": "listOrders",
"parameters": [
{
"name": "status",
"in": "query",
"schema": { "type": "string" }
}
],
"responses": {
"200": {
"description": "成功返回订单列表",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/OrderList" }
}
}
}
}
}
}
}
}
常见陷阱: YAML 对缩进敏感,禁止使用 Tab 键;多行字符串使用
|(保留换行)或 >(折叠换行)。JSON 中 $ref 引用路径必须严格匹配,大小写敏感。
2.3 路径与操作
paths 对象是 API 的路由映射表。每个路径下可定义多个 HTTP 操作(method),形成完整的端点契约。
路径定义规则:
- 静态路径:
/users、/orders,直接匹配固定资源。 - 路径参数:
/users/{userId},使用花括号声明变量,在parameters中定义类型。 - 操作对象: 每个路径下可包含
get、post、put、delete、patch等。
操作对象核心字段:
| 字段 | 说明 | 契约测试关注点 |
|---|---|---|
operationId |
操作的唯一标识符 | 用于生成测试用例名称 |
parameters |
路径、查询、请求头参数定义 | 验证必填参数、参数类型 |
requestBody |
POST/PUT 的请求体描述 | 验证请求体结构与 content-type |
responses |
所有可能的 HTTP 状态码及响应结构 | 验证响应状态码、响应体 schema |
security |
操作级别的安全要求 | 验证鉴权 token 传递 |
性能调优关联: 路径参数(如
{userId})在压测时需替换为实际值;operationId 用于在性能报告中定位具体接口;parameters 中的 required 字段决定压测脚本的入参构造策略。
2.4 请求 / 响应模型
OpenAPI 3.0 使用 requestBody 和 responses 精确描述 API 的输入输出契约。这是契约测试的核心验证对象,也是性能调优时构造压测 payload 的依据。
2.4.1 请求模型
请求模型包含三个维度:
- 参数(parameters): 路径参数、查询参数、请求头参数。每个参数需定义
name、in(位置)、schema(类型约束)、required(是否必填)。 - 请求体(requestBody): 用于 POST、PUT、PATCH。需声明
content.type(如application/json)和对应的schema。 - 安全方案(security): 声明操作所需的认证方式(如 Bearer Token、API Key)。
请求参数定义示例:
parameters:
- name: orderId
in: path
required: true
schema:
type: integer
minimum: 1
- name: pageSize
in: query
required: false
schema:
type: integer
default: 20
maximum: 100
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
2.4.2 响应模型
响应模型按 HTTP 状态码组织,每个状态码对应一个响应对象:
| 状态码 | 语义 | 契约测试验证点 |
|---|---|---|
200 |
成功响应 | 响应体结构、必填字段、数据类型 |
201 |
创建成功 | 返回资源 ID 或 Location 头 |
400 |
请求参数错误 | 错误信息格式、错误码字段 |
401 |
未认证 | WWW-Authenticate 头、错误体 |
404 |
资源不存在 | 错误描述、资源标识 |
500 |
服务端错误 | 是否返回通用错误结构 |
响应定义示例:
responses:
'200':
description: 订单详情
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'404':
description: 订单不存在
content:
application/json:
schema:
type: object
properties:
code:
type: string
example: "ORDER_NOT_FOUND"
message:
type: string
example: "未找到指定订单"
性能调优关联: 响应模型中的
schema 定义了返回字段的类型和大小。在压测时,响应体大小直接影响网络传输耗时和序列化开销。大响应体(如包含嵌套数组)应作为性能瓶颈排查的切入点。
2.5 组件复用与 $ref 引用
components 对象是 OpenAPI 3.0 的复用机制,避免在多个路径中重复定义相同的数据结构。契约测试中,组件定义是验证响应体结构的权威来源。
组件分类:
| 组件类型 | 用途 | 示例 |
|---|---|---|
schemas |
数据模型定义(对象、数组、枚举) | User、OrderList |
parameters |
可复用的参数定义 | pageToken、locale |
responses |
可复用的响应结构 | NotFound、Unauthorized |
requestBodies |
可复用的请求体定义 | CreateUserBody |
headers |
可复用的响应头定义 | X-RateLimit-Remaining |
$ref 引用语法:
# 引用 schema 组件
schema:
$ref: '#/components/schemas/Order'
# 引用参数组件
parameters:
- $ref: '#/components/parameters/pageToken'
# 引用响应组件
responses:
'404':
$ref: '#/components/responses/NotFound'
契约测试注意事项:
$ref 引用在解析时需注意循环引用问题。性能调优时,组件复用程度影响契约文件大小,过大的契约文件会增加解析耗时。建议将大型 schema 拆分为多个文件,使用 $ref 跨文件引用。
2.6 契约测试视角的 OpenAPI 最佳实践
- 显式声明所有响应状态码: 包括 4xx 和 5xx,确保契约测试覆盖异常路径。
- 使用
example字段: 为每个 schema 属性提供示例值,便于自动生成测试数据。 - 定义
nullable和required: 明确字段的可空性和必填性,避免测试用例遗漏边界情况。 - 统一错误响应结构: 在
components/responses中定义全局错误格式,确保所有接口的错误体一致。 - 标注
deprecated操作: 弃用接口在契约中标记,性能压测时自动跳过。
性能调优提示: 在 OpenAPI 契约中为每个操作添加
x-performance-latency-sla 扩展字段,标注该接口的预期 P99 延迟阈值。压测工具可读取该字段自动判断性能是否达标。