OpenAPI 规范基础:版本历史、3.0 与 3.1 区别及文档结构
OpenAPI 规范(原 Swagger 规范)是描述 RESTful API 的行业标准,它定义了一种与语言无关的接口描述格式,使人和机器都能理解 API 的能力。理解其版本演进、核心差异以及文档的基本结构,是进行契约校验的第一步。
2.1 OpenAPI 规范版本历史
OpenAPI 规范经历了从 Swagger 到标准化规范的演进过程,每个主要版本都带来了重要的能力提升。
| 版本 | 发布时间 | 关键特性 | 状态 |
|---|---|---|---|
| Swagger 2.0 | 2014 年 | 奠定基础:路径、参数、响应、模型定义 | 广泛使用,但已停止更新 |
| OpenAPI 3.0.0 | 2017 年 | 引入 components、requestBody、links、callbacks、oneOf/anyOf |
当前主流版本 |
| OpenAPI 3.0.1 ~ 3.0.3 | 2018 ~ 2020 年 | 错误修复、nullable 类型澄清、示例增强 |
3.0.x 系列稳定版 |
| OpenAPI 3.1.0 | 2021 年 | 完全兼容 JSON Schema 2020-12、webhooks、license 标识符 |
最新版本,逐步普及 |
版本选择建议: 新项目建议直接使用 OpenAPI 3.1.0,以利用 JSON Schema 2020-12 的全部能力。现有 3.0.x 项目可继续维护,迁移成本主要在于
nullable 和 example 字段的调整。
2.2 OpenAPI 3.0 与 3.1 的核心区别
3.1 版本并非简单的增量更新,而是对规范底层 Schema 语言的一次重大升级。以下表格列出了最关键的差异点:
| 对比维度 | OpenAPI 3.0 | OpenAPI 3.1 |
|---|---|---|
| Schema 语言 | 使用 OpenAPI Schema Object(JSON Schema Draft 5 的子集 + 扩展) | 完全采用 JSON Schema 2020-12,支持 $id、$defs、unevaluatedProperties 等 |
| nullable | 使用 nullable: true 扩展字段 |
使用 JSON Schema 原生 type: ["string", "null"] 或 anyOf |
| example / examples | example 字段在 Schema 和 Media Type 级别 |
统一使用 JSON Schema 的 examples(数组),example 仍保留但推荐使用 examples |
| webhooks | 不支持,需通过 callbacks 模拟 |
新增顶级 webhooks 字段,原生支持出站回调描述 |
| 路径参数 | 路径模板使用 {param},需在 parameters 中声明 |
路径模板语法不变,但支持通过 JSON Schema 的 pattern 和 contentEncoding 增强校验 |
| info 对象 | license 使用 url 字段 |
license 新增 identifier 字段(如 MIT、Apache-2.0) |
| JSON 引用 | 仅支持 $ref,不支持 $id |
支持 $id 和 $ref,可跨文档引用 |
迁移注意: 从 3.0 迁移到 3.1 时,
nullable: true 必须改为 type: ["string", "null"] 或使用 anyOf。如果工具链尚未完全支持 JSON Schema 2020-12,建议先进行兼容性测试。
以下 SVG 图展示了从 OpenAPI 3.0 到 3.1 的核心 Schema 语言升级路径:
2.3 OpenAPI 文档的基本结构
一个标准的 OpenAPI 文档(JSON 或 YAML 格式)由多个顶级对象组成,它们共同描述了 API 的全貌。以下是文档的骨架结构:
openapi: 3.1.0
info:
title: 示例 API
version: 1.0.0
description: 这是一个示例 API 文档
servers:
- url: https://api.example.com/v1
paths:
/users:
get:
summary: 获取用户列表
responses:
'200':
description: 成功返回用户列表
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
security:
- ApiKeyAuth: []
tags:
- name: users
description: 用户相关操作
文档的顶级字段及其职责如下表所示:
| 顶级字段 | 必需性 | 描述 |
|---|---|---|
openapi |
必需 | 声明使用的 OpenAPI 规范版本号(如 3.0.3、3.1.0) |
info |
必需 | 提供 API 的元数据:标题、版本、描述、许可、联系方式 |
servers |
可选 | 定义 API 的基础 URL 列表,支持变量替换 |
paths |
必需 | API 的端点路径及每个路径支持的 HTTP 方法(GET、POST 等) |
components |
可选 | 可复用的组件容器:schemas、parameters、responses、requestBodies、securitySchemes 等 |
security |
可选 | 全局安全要求,引用 components/securitySchemes 中定义的方案 |
tags |
可选 | 用于对路径进行逻辑分组的标签列表,便于文档组织 |
externalDocs |
可选 | 指向 API 外部文档的链接 |
webhooks |
可选 | (3.1 新增)描述 API 向外发送的回调事件 |
以下 SVG 图展示了 OpenAPI 文档的完整结构层次:
契约校验视角: 在契约测试中,
paths 定义了 API 的端点契约(请求路径、方法、参数、请求体),components/schemas 定义了数据模型契约(字段类型、约束、格式)。校验工具会逐字段比对实际请求/响应与文档中的 Schema 定义是否一致。
2.4 关键结构详解:paths 与 components
paths 和 components 是契约校验中最常被引用的两个顶级对象,理解它们的嵌套关系至关重要。
paths 对象
每个路径下可定义多个操作(HTTP 方法),每个操作包含:
- parameters:路径参数、查询参数、请求头参数
- requestBody:请求体内容及媒体类型
- responses:每个状态码对应的响应结构
- security:操作级别的安全要求(覆盖全局)
components 对象
用于定义可复用的组件,避免重复定义:
- schemas:数据模型定义(最常用)
- parameters:可复用的参数定义
- responses:可复用的响应定义
- requestBodies:可复用的请求体定义
- securitySchemes:认证方案定义(API Key、OAuth2、HTTP Auth)
- headers:可复用的响应头定义
- links:操作间的关联关系
- callbacks:异步回调定义
最佳实践: 始终将数据模型定义在
components/schemas 中,通过 $ref 引用。这不仅能减少重复,还能让契约校验工具在发现 Schema 变更时,精准定位到影响范围。