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 文档中五个顶层字段的层级关系与数据流向:

OpenAPI 文档五大核心对象关系图 openapi: "3.0.3" info title, version, description contact, license servers url, description, variables paths /users, /orders, ... get, post, put, delete components schemas, parameters, responses requestBodies, headers 说明 openapi 字段声明规范版本,info 提供元数据,servers 定义基 URL, paths 描述具体端点,components 提供可复用组件。paths 通过 $ref 引用 components。

3.7 五大字段的缓存影响矩阵

在缓存策略设计中,每个顶层字段的变更都会对缓存产生不同范围的影响。下表总结了各字段变更时的缓存失效范围:

字段 变更类型 缓存失效范围 建议策略
openapi 版本升级 整个文档 使用版本号作为缓存键前缀
info 元信息更新 文档元数据缓存 单独缓存 info,不与其他字段耦合
servers URL 变更 所有路径的基 URL 缓存 将 servers 哈希值加入缓存键
paths 端点新增/修改/删除 受影响的路径及其子操作 按路径粒度缓存,支持局部失效
components Schema 或参数变更 所有引用该组件的路径 使用组件版本号或哈希值追踪
常见陷阱: 很多团队只关注 paths 的变更,忽略了 components 的更新。当 components/schemas 中的 User 模型增加字段时,所有返回 User 对象的端点都应触发缓存刷新,否则客户端将拿到过时的数据结构。

3.8 最佳实践:契约的领域边界

在大型项目中,建议将 OpenAPI 文档按领域边界拆分为多个文件,通过 $ref 进行组合。这有助于隔离缓存影响范围:

  1. 按微服务拆分: 每个微服务维护独立的 OpenAPI 文档,只包含自己的 paths 和 components。
  2. 按版本拆分: 不同版本的 API 使用独立的文档,避免版本混淆导致缓存污染。
  3. 按变更频率拆分: 将稳定的基础 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 管理中能显著降低缓存刷新成本。