2. OpenAPI 基础结构:顶层字段详解

OpenAPI 文档的核心是一个符合规范的 JSON 或 YAML 文件,它通过一组顶层字段完整描述了一个 API 的接口、数据模型、认证方式和服务器信息。理解这些顶层字段是编写、阅读和维护 OpenAPI 文档的基础。本章将逐一剖析 openapi、info、servers、paths 和 components 这五个必选或常用字段的结构与用法。

2.1 顶层字段总览

一个标准的 OpenAPI 3.x 文档,其根对象包含以下核心字段。下表列出了每个字段的用途与出现要求:

字段名 类型 必选 用途说明
openapi string 是 声明使用的 OpenAPI 规范版本号,例如 "3.0.3"。
info object 是 提供 API 的元数据:标题、版本、描述、联系人、许可信息。
servers array 否 定义 API 的基础 URL 列表,客户端将据此发起请求。
paths object 是 描述所有可用的 API 端点及其操作(GET、POST 等)。
components object 否 集中存放可复用的数据模型(schemas)、参数、响应、安全方案等。
tags array 否 用于对路径操作进行逻辑分组,便于文档导航。
externalDocs object 否 指向 API 外部文档的链接。
版本提示: 本课程基于 OpenAPI 3.0.3 规范。如果你使用的是 OpenAPI 2.0(Swagger),顶层字段结构有较大差异,建议优先升级到 3.x。

2.2 字段详解与代码示例

2.2.1 openapi — 规范版本声明

该字段的值必须是语义化版本号字符串。它告诉解析工具该文档遵循哪个版本的规范。目前主流版本为 3.0.3 或 3.1.0。

openapi: "3.0.3"

2.2.2 info — API 元数据

info 对象包含 API 的标题、描述和版本号,是文档的“身份证”。

info:
  title: 电商订单服务 API
  description: 提供订单创建、查询、取消等核心功能。
  version: "2.1.0"
  contact:
    name: API 支持团队
    email: api-support@example.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0

2.2.3 servers — 服务器地址

定义 API 的基础 URL。可以配置多个服务器(如开发、测试、生产环境),客户端根据环境选择使用。

servers:
  - url: https://api.example.com/v2
    description: 生产环境
  - url: https://staging-api.example.com/v2
    description: 预发布环境

2.2.4 paths — 端点与操作

paths 是文档的核心,它按路径组织所有 HTTP 方法。每个路径下可以定义请求参数、请求体、响应和安全性要求。

paths:
  /orders:
    get:
      summary: 获取订单列表
      operationId: listOrders
      parameters:
        - name: status
          in: query
          schema:
            type: string
      responses:
        '200':
          description: 成功返回订单列表
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderList'
    post:
      summary: 创建新订单
      operationId: createOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
      responses:
        '201':
          description: 订单创建成功

2.2.5 components — 可复用组件

将重复使用的数据模型、参数、响应、安全方案等抽取到 components 中,通过 $ref 引用,避免冗余。

components:
  schemas:
    Order:
      type: object
      properties:
        id:
          type: integer
        total:
          type: number
        status:
          type: string
    CreateOrderRequest:
      type: object
      properties:
        productId:
          type: integer
        quantity:
          type: integer
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

2.3 顶层字段关系结构图

下面的 SVG 图展示了 OpenAPI 文档顶层字段之间的层级与引用关系,帮助你建立整体认知:

OpenAPI 文档顶层字段结构 OpenAPI 根对象 openapi (版本) info (元数据) servers (服务器) paths (路径) components /orders /users schemas GET POST 关键说明: • openapi 和 info 是必选字段,缺少会导致文档无效。 • paths 是必选字段,即使没有端点也需声明为空对象 {}。 • servers 和 components 为可选,但强烈建议使用 components 管理可复用模型。 • 所有引用通过 $ref 指向 components 下的定义,实现“定义一次,多处复用”。

2.4 字段使用原则与常见误区

最佳实践:
  • 始终在 info 中填写 contact 信息,方便使用者反馈问题。
  • 为每个路径操作定义唯一的 operationId,便于代码生成工具生成客户端方法名。
  • 将复杂的数据模型(如嵌套对象、枚举)抽取到 components/schemas 中,通过 $ref 引用。
  • 在 servers 中列出所有环境(开发、测试、生产),并添加 description 说明用途。
常见误区:
  • 在 paths 中直接内联复杂模型定义,导致文档冗长且难以维护。
  • 忘记声明 openapi 版本,导致解析工具无法识别文档格式。
  • 多个路径重复定义相同的参数(如分页参数),应使用 components/parameters 统一管理。
  • 在 servers 中只写一个 URL,忽略了多环境切换的需求。

2.5 完整示例:最小可用 OpenAPI 文档

下面是一个包含所有必选字段和常用可选字段的完整示例,你可以将其作为编写新 API 文档的起点:

openapi: "3.0.3"
info:
  title: 用户管理 API
  description: 提供用户注册、登录、信息查询功能。
  version: "1.0.0"
  contact:
    name: 后端团队
    email: backend@example.com
servers:
  - url: https://api.example.com/v1
    description: 生产服务器
paths:
  /users:
    get:
      summary: 获取用户列表
      operationId: getUsers
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserList'
    post:
      summary: 创建用户
      operationId: createUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUser'
      responses:
        '201':
          description: 用户创建成功
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
    UserList:
      type: array
      items:
        $ref: '#/components/schemas/User'
    CreateUser:
      type: object
      required:
        - name
        - email
      properties:
        name:
          type: string
        email:
          type: string