3. OpenAPI 文档核心组件
一份完整的 OpenAPI 文档由多个顶层对象组成,它们共同定义了 API 的元信息、网络地址、端点路由、可复用组件以及标签分类。理解这五个核心组件是进行契约校验的前提。
3.1 核心组件总览
下表列出了 OpenAPI 文档中五个必选或常用的顶层字段及其职责:
| 字段名 | 类型 | 必选 | 职责描述 |
|---|---|---|---|
info |
Info Object | 是 | 描述 API 的标题、版本、描述、联系人、许可信息 |
servers |
[Server Object] | 否(推荐) | 定义 API 的基础 URL 与环境(生产、测试、本地) |
paths |
Paths Object | 是 | 声明所有可用的 API 端点及其支持的 HTTP 方法 |
components |
Components Object | 否(推荐) | 集中存放可复用的 schema、参数、响应、请求体等 |
tags |
[Tag Object] | 否 | 为端点分组,提升文档可读性与工具链分类能力 |
契约校验要点: 校验器会首先检查
info 和 paths 是否存在。缺少 servers 或 components 不会导致文档无效,但会降低契约的可移植性和可测试性。
3.2 info 对象:API 的身份证
info 对象提供 API 的元数据,是消费者识别 API 身份的第一入口。其核心字段包括:
- title(必填):API 的名称,如“用户管理服务”。
- version(必填):文档版本号,建议遵循语义化版本(SemVer),如
1.0.0。 - description:对 API 功能的详细说明,支持 CommonMark 语法。
- contact:维护团队的联系方式(name、url、email)。
- license:API 使用的许可协议(name、url)。
info:
title: 电商订单服务
version: "2.1.0"
description: 提供订单创建、查询、退款等核心能力
contact:
name: API 团队
email: api@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
3.3 servers 对象:API 的网络地址
servers 是一个数组,每个元素定义一个服务器。它替代了 Swagger 2.0 中的 host、basePath 和 schemes,提供了更灵活的多环境支持。
| 字段 | 说明 | 示例 |
|---|---|---|
url |
基础 URL,支持模板变量(如 {env}) |
https://api.example.com/v2 |
description |
对该服务器的描述 | 生产环境 |
variables |
URL 模板变量的默认值与枚举 | env: { default: prod, enum: [prod, staging] } |
servers:
- url: https://{env}.api.example.com/v2
description: 动态环境
variables:
env:
default: prod
enum:
- prod
- staging
- dev
- url: http://localhost:8080
description: 本地开发
3.4 paths 对象:API 的路由地图
paths 是 OpenAPI 文档的核心,它定义了所有可访问的端点及其操作。每个路径下可以包含一个或多个 HTTP 方法(get、post、put、delete 等)。
- 路径模板:支持路径参数,如
/users/{userId}。 - 操作对象:每个方法下可定义
parameters、requestBody、responses、tags等。 - summary / description:对端点的简短说明和详细描述。
paths:
/orders:
get:
tags: [订单]
summary: 获取订单列表
parameters:
- name: status
in: query
schema:
type: string
responses:
'200':
description: 成功返回订单列表
post:
tags: [订单]
summary: 创建新订单
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrder'
responses:
'201':
description: 订单创建成功
契约校验核心: 校验器会逐条检查
paths 中的每个端点:路径格式是否合法、HTTP 方法是否被允许、参数定义是否完整、响应状态码是否覆盖。任何缺失或格式错误都会导致校验失败。
3.5 components 对象:可复用组件仓库
components 是一个容器,用于集中定义可被 $ref 引用的对象。它避免了在多个端点中重复定义相同的 schema、参数或响应。
components 内部包含以下常用分类:
| 分类键 | 用途 | 引用示例 |
|---|---|---|
schemas |
数据模型定义(JSON Schema) | $ref: '#/components/schemas/User' |
parameters |
可复用的路径/查询/头参数 | $ref: '#/components/parameters/pageSize' |
responses |
可复用的响应结构 | $ref: '#/components/responses/NotFound' |
requestBodies |
可复用的请求体 | $ref: '#/components/requestBodies/UserCreate' |
headers |
可复用的响应头 | $ref: '#/components/headers/X-Request-Id' |
securitySchemes |
认证方案定义 | $ref: '#/components/securitySchemes/BearerAuth' |
components:
schemas:
User:
type: object
required: [id, name, email]
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
parameters:
pageSize:
name: page_size
in: query
schema:
type: integer
default: 20
responses:
NotFound:
description: 资源未找到
content:
application/json:
schema:
type: object
properties:
code:
type: integer
message:
type: string
3.6 tags 对象:端点的分类标签
tags 是一个顶层数组,用于对 paths 中的端点进行逻辑分组。每个标签可以包含名称和描述,工具链(如 Swagger UI)会根据标签对端点进行分组展示。
tags:
- name: 订单
description: 订单创建、查询、退款相关接口
- name: 用户
description: 用户注册、登录、信息管理
- name: 商品
description: 商品浏览、搜索、详情
在 paths 中引用标签:
paths:
/products:
get:
tags: [商品]
summary: 获取商品列表
常见误区: 标签在
tags 顶层定义后,必须在 paths 中显式引用才会生效。仅定义顶层标签而不在端点中引用,不会产生任何分组效果。
3.7 核心组件关系图
下图展示了五个核心组件在 OpenAPI 文档中的层级关系与数据流向:
3.8 组件间的引用关系
下图展示了 paths 与 components 之间通过 $ref 建立的引用链路,这是契约校验中解析依赖的关键路径:
3.9 契约校验视角下的核心组件
从契约测试的角度,五个核心组件各自承担不同的校验职责:
| 组件 | 校验关注点 | 常见校验失败原因 |
|---|---|---|
info |
必填字段是否存在、版本格式 | 缺少 title 或 version;version 不符合 SemVer |
servers |
URL 格式是否合法、变量是否定义 | URL 缺少协议头;变量未提供默认值 |
paths |
路径格式、方法合法性、参数完整性、响应覆盖 | 路径包含非法字符;缺少 4xx/5xx 响应定义 |
components |
引用是否可解析、循环引用检测 | $ref 指向不存在的组件;出现无限递归 |
tags |
标签名称是否在 paths 中被引用 | 定义了标签但未在任何端点中使用 |
最佳实践: 在编写 OpenAPI 文档时,优先将复杂的数据模型和通用参数放入
components,然后在 paths 中通过 $ref 引用。这不仅能减少重复代码,还能让契约校验器更高效地定位问题。