2. OpenAPI 规范基础:历史、核心结构与文件组成
OpenAPI 规范(原 Swagger 规范)是 RESTful API 契约的事实标准。理解其演进脉络、3.0 版的核心骨架以及 YAML/JSON 文件的组成要素,是划定 API 契约领域边界的第一步。本章从这三个维度建立基础认知。
2.1 OpenAPI 规范的历史演进
规范经历了从 Swagger 到 OpenAPI 的品牌与治理转变,每一次大版本都显著影响了契约的表达能力。
| 版本 | 发布时间 | 关键变化 | 治理组织 |
|---|---|---|---|
| Swagger 1.x | 2011 | 首次定义 REST API 描述格式,支持 JSON | Wordnik / 社区 |
| Swagger 2.0 | 2014 | 引入 definitions、parameters、responses 可复用组件;成为业界主流 |
Swagger 社区 |
| OpenAPI 3.0 | 2017 | 重构为 components 对象;新增 oneOf/anyOf/allOf 组合模型;分离请求体与参数;支持回调、链接 |
OpenAPI Initiative (Linux Foundation) |
| OpenAPI 3.1 | 2021 | 完全兼容 JSON Schema 2020-12;引入 webhooks 顶层字段;移除 nullable 改用 type: ["string", "null"] |
OpenAPI Initiative |
领域边界提示:OpenAPI 3.0 是当前最广泛采用的稳定版本。本课程所有契约边界分析均以 OpenAPI 3.0.x 为基准,部分高级话题会对比 3.1 的差异。
2.2 OpenAPI 3.0 核心结构
一个 OpenAPI 3.0 文档由四个顶层区域构成,它们共同定义了 API 的契约边界:
- 元信息层(
openapi、info、servers)—— 声明规范版本、API 标题、版本号、基础 URL。 - 路径层(
paths)—— 按资源路径组织所有端点及其操作(GET/POST/PUT/DELETE 等)。 - 组件层(
components)—— 集中定义可复用的 Schema、参数、请求体、响应、安全方案等。 - 增强层(
tags、externalDocs、security)—— 提供分组、外部文档、全局安全声明。
2.3 OpenAPI 文件的基本组成
一个完整的 OpenAPI 3.0 文件(YAML 或 JSON)包含以下必需和可选字段。以下是一个最小可用的契约示例:
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:
type: array
items:
$ref: "#/components/schemas/Order"
components:
schemas:
Order:
type: object
properties:
id:
type: integer
customerName:
type: string
totalAmount:
type: number
required:
- id
- customerName
2.4 各组成要素详解
| 字段 | 必需 | 说明 | 领域边界意义 |
|---|---|---|---|
openapi |
是 | 声明使用的 OpenAPI 规范版本号 | 确定契约解析规则与能力集 |
info |
是 | API 的元数据:标题、版本、描述、联系人等 | 标识 API 所属业务域与版本边界 |
servers |
否(推荐) | 一个或多个基础 URL,可带变量 | 划定 API 的网络可达边界 |
paths |
是 | 按资源路径组织的端点定义 | 定义资源边界与操作集合 |
components |
否 | 可复用的 Schema、参数、请求体、响应、安全方案 | 统一类型系统,防止契约碎片化 |
tags |
否 | 用于对路径进行逻辑分组 | 映射到领域子域或模块边界 |
security |
否 | 全局安全要求声明 | 定义访问控制边界 |
关键认知:OpenAPI 文件不仅仅是接口文档,它是一份可执行的契约。每个字段都在划定 API 的某个领域边界——资源边界、类型边界、版本边界、安全边界。在后续章节中,我们将基于这些边界进行领域驱动设计分析。
2.5 路径与操作的契约结构
每个路径下的操作(Operation)是契约的核心单元,其内部结构决定了 API 的行为边界:
- operationId —— 操作的唯一标识符,在代码生成和领域事件溯源中作为方法签名。
- parameters —— 路径参数、查询参数、请求头参数,定义输入边界。
- requestBody —— 仅适用于 POST/PUT/PATCH,描述请求体的媒体类型与 Schema。
- responses —— 按 HTTP 状态码组织的响应定义,包含媒体类型与 Schema。
- security —— 可覆盖全局安全策略,定义操作级安全边界。
常见误区:初学者常将
requestBody 与 parameters 混淆。在 OpenAPI 3.0 中,parameters 仅用于路径、查询、请求头、Cookie 参数;请求体必须使用独立的 requestBody 字段。这一分离使得契约的输入边界更加清晰。
2.6 组件复用与契约边界
components 对象是 OpenAPI 3.0 最重要的架构改进之一。它将类型定义从路径中抽离,形成独立的类型系统:
components:
schemas:
Order:
type: object
properties:
id: { type: integer }
items:
type: array
items:
$ref: "#/components/schemas/OrderItem"
OrderItem:
type: object
properties:
productId: { type: integer }
quantity: { type: integer }
price: { type: number }
parameters:
orderId:
name: orderId
in: path
required: true
schema: { type: integer }
requestBodies:
CreateOrder:
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
通过 $ref 引用,路径层可以复用组件层的定义。这种机制带来的领域边界优势:
- 单一事实来源 —— Order 类型只定义一次,所有路径引用同一 Schema。
- 类型一致性 —— 避免不同路径对同一资源定义不一致的字段。
- 版本管理 —— 修改组件 Schema 即可全局生效,便于契约版本演进。
- 领域模型映射 ——
components/schemas直接对应领域驱动设计中的聚合根、实体、值对象。
实践建议:在编写 OpenAPI 契约时,优先将业务实体定义为
components/schemas,路径层只做引用。这能强制团队在 API 设计阶段就思考领域模型的边界,而非仅仅罗列端点。