3. OpenAPI 基础结构:五大核心对象
OpenAPI 规范(OAS)定义了一套标准化的元数据格式,用于描述 HTTP API 的契约。一个合法的 OpenAPI 文档由五个顶层字段构成其骨架:openapi、info、servers、paths 和 components。理解这五个字段的职责与边界,是构建可维护、可缓存 API 契约的第一步。
核心原则: OpenAPI 文档的顶层字段顺序并不强制,但推荐按“版本声明 → 元信息 → 服务器 → 路径 → 组件”的逻辑顺序排列,以提升可读性。
3.1 openapi 字段:版本声明
openapi 字段是文档的版本标识,必须位于文档根节点。它使用 SemVer 格式,声明文档所遵循的 OpenAPI 规范版本。
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
openapi |
string | 是 | 规范版本号,例如 "3.0.3" 或 "3.1.0" |
openapi: "3.0.3"
版本选择建议: 新项目推荐使用
3.0.3(稳定)或 3.1.0(支持 JSON Schema 2020-12)。版本号决定了后续字段的可用特性,例如 3.1.0 允许在 info 中使用 summary 字段。
3.2 info 对象:API 元信息
info 对象提供 API 的元数据,如标题、版本、描述和联系人信息。它是 API 文档的“身份证”。
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
title |
string | 是 | API 的名称 |
version |
string | 是 | API 的版本号(非规范版本) |
description |
string | 否 | API 的详细描述,支持 CommonMark 语法 |
contact |
Contact Object | 否 | API 维护者的联系信息 |
license |
License Object | 否 | API 的许可证信息 |
info:
title: 用户管理 API
version: "2.1.0"
description: 提供用户注册、登录、资料查询等核心功能。
contact:
name: API 支持团队
email: api-support@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
3.3 servers 对象:连接端点
servers 对象定义 API 的基 URL 和可选的变量替换规则。它告诉客户端“去哪里调用这个 API”。
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
url |
string | 是 | 服务器 URL,支持变量模板(如 {protocol}) |
description |
string | 否 | 服务器的用途说明 |
variables |
Map[string, Server Variable Object] | 否 | URL 模板变量的定义 |
servers:
- url: https://api.example.com/v2
description: 生产环境
- url: https://staging-api.example.com/v2
description: 预发布环境
缓存影响: 当
servers 中包含多个 URL 时,缓存键必须包含服务器标识。如果使用变量模板(如 {region}),每个变量组合都应视为独立的缓存空间,否则可能导致跨环境数据污染。
3.4 paths 对象:API 的核心契约
paths 对象是 OpenAPI 文档的核心,它按路径(如 /users)组织所有可用的 API 端点及其操作(GET、POST 等)。每个路径下可以定义多个 HTTP 方法。
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
/{path} |
Path Item Object | 是 | 相对路径,以 / 开头,支持路径参数(如 /users/{userId}) |
summary |
string | 否 | 路径的简短摘要(3.1.0 新增) |
description |
string | 否 | 路径的详细描述 |
paths:
/users:
get:
summary: 获取用户列表
operationId: listUsers
responses:
'200':
description: 成功返回用户列表
post:
summary: 创建新用户
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 用户创建成功
3.5 components 对象:可复用组件仓库
components 对象是一个容器,用于存放可复用的 Schema、参数、响应、请求体、头信息等。它通过 $ref 引用机制被 paths 或其他对象调用,避免重复定义。
| 字段 | 类型 | 说明 |
|---|---|---|
schemas |
Map[string, Schema Object] | 数据模型定义 |
responses |
Map[string, Response Object] | 可复用的响应定义 |
parameters |
Map[string, Parameter Object] | 可复用的参数定义 |
requestBodies |
Map[string, Request Body Object] | 可复用的请求体定义 |
headers |
Map[string, Header Object] | 可复用的头信息定义 |
securitySchemes |
Map[string, Security Scheme Object] | 安全认证方案定义 |
links |
Map[string, Link Object] | 链接关系定义 |
callbacks |
Map[string, Callback Object] | 回调定义 |
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
required:
- id
- name
parameters:
userId:
name: userId
in: path
required: true
schema:
type: integer
缓存与组件: 当
components 中的 Schema 发生变化时,所有引用该 Schema 的路径响应都应视为缓存失效。建议在缓存键中包含 components 的哈希值,或使用版本号管理组件变更。
3.6 五大对象的关系与边界
下图展示了 OpenAPI 文档中五个顶层字段的层级关系与数据流向:
3.7 五大字段的缓存影响矩阵
在缓存策略设计中,每个顶层字段的变更都会对缓存产生不同范围的影响。下表总结了各字段变更时的缓存失效范围:
| 字段 | 变更类型 | 缓存失效范围 | 建议策略 |
|---|---|---|---|
openapi |
版本升级 | 整个文档 | 使用版本号作为缓存键前缀 |
info |
元信息更新 | 文档元数据缓存 | 单独缓存 info,不与其他字段耦合 |
servers |
URL 变更 | 所有路径的基 URL 缓存 | 将 servers 哈希值加入缓存键 |
paths |
端点新增/修改/删除 | 受影响的路径及其子操作 | 按路径粒度缓存,支持局部失效 |
components |
Schema 或参数变更 | 所有引用该组件的路径 | 使用组件版本号或哈希值追踪 |
常见陷阱: 很多团队只关注
paths 的变更,忽略了 components 的更新。当 components/schemas 中的 User 模型增加字段时,所有返回 User 对象的端点都应触发缓存刷新,否则客户端将拿到过时的数据结构。
3.8 最佳实践:契约的领域边界
在大型项目中,建议将 OpenAPI 文档按领域边界拆分为多个文件,通过 $ref 进行组合。这有助于隔离缓存影响范围:
- 按微服务拆分: 每个微服务维护独立的 OpenAPI 文档,只包含自己的
paths和components。 - 按版本拆分: 不同版本的 API 使用独立的文档,避免版本混淆导致缓存污染。
- 按变更频率拆分: 将稳定的基础 Schema(如 User、Order)与频繁变动的业务端点分离,分别管理缓存生命周期。
# 主文档:api.yaml
openapi: "3.0.3"
info:
title: 电商平台 API
version: "1.0.0"
servers:
- url: https://api.example.com/v1
paths:
/users:
$ref: './paths/users.yaml'
/orders:
$ref: './paths/orders.yaml'
components:
schemas:
User:
$ref: './components/user.yaml'
Order:
$ref: './components/order.yaml'
缓存粒度控制: 使用
$ref 拆分后,每个子文件可以独立计算哈希值。当某个子文件变更时,只有引用该文件的父文档需要更新缓存,其他文档不受影响。这在大规模 API 管理中能显著降低缓存刷新成本。