4. OpenAPI 规范入门:OpenAPI 3.0 核心概念、YAML/JSON 格式、路径与操作定义

OpenAPI 规范(原 Swagger 规范)是业界标准的 RESTful API 描述语言。它提供了一种与语言无关的接口定义方式,使得人类和机器都能理解 API 的能力,无需访问源码、文档或网络流量检测。本章将带你掌握 OpenAPI 3.0 的核心概念、两种序列化格式以及路径与操作的定义方法。

4.1 OpenAPI 3.0 核心概念

OpenAPI 3.0 文档是一个自包含的 API 描述文件,通常命名为 openapi.yaml 或 openapi.json。其顶层结构由以下几个核心对象组成:

顶层字段 类型 说明
openapi string 规范版本号,3.0.x 系列必须写 "3.0.3"
info Info Object API 元信息:标题、版本、描述、联系人等
servers [Server Object] API 的基础 URL 列表,可包含变量
paths Paths Object API 的所有端点路径及其操作
components Components Object 可复用的 schema、参数、响应、请求体等
tags [Tag Object] 用于 API 端点分组的逻辑标签
externalDocs External Documentation Object 外部文档链接
版本选择建议: 当前稳定版本为 3.0.3。OpenAPI 3.1 已发布,但工具链兼容性仍在完善中。本课程所有示例均基于 3.0.3。

4.2 YAML 与 JSON 格式对比

OpenAPI 规范支持 YAML 和 JSON 两种序列化格式。YAML 因其可读性高、注释支持好,成为社区首选;JSON 则在机器生成和某些工具链中更常见。

特性 YAML JSON
可读性 高,缩进层级清晰 中,括号嵌套较多
注释 支持 # 注释 不支持原生注释
多行字符串 支持 | 和 > 块标量 需使用 \n 转义
引用 支持锚点 & 和别名 * 不支持
工具链兼容性 部分工具对复杂 YAML 解析有坑 几乎所有工具完美支持
文件大小 通常比 JSON 小 20-30% 略大,但差异不明显

以下展示同一 API 描述在两种格式下的写法:

# openapi.yaml
openapi: "3.0.3"
info:
  title: 用户管理 API
  version: "1.0.0"
  description: 提供用户注册、登录、信息查询功能
servers:
  - url: https://api.example.com/v1
paths:
  /users:
    get:
      summary: 获取用户列表
      responses:
        '200':
          description: 成功返回用户数组
// openapi.json
{
  "openapi": "3.0.3",
  "info": {
    "title": "用户管理 API",
    "version": "1.0.0",
    "description": "提供用户注册、登录、信息查询功能"
  },
  "servers": [
    { "url": "https://api.example.com/v1" }
  ],
  "paths": {
    "/users": {
      "get": {
        "summary": "获取用户列表",
        "responses": {
          "200": {
            "description": "成功返回用户数组"
          }
        }
      }
    }
  }
}
YAML 缩进陷阱: YAML 使用空格缩进,禁止使用 Tab。缩进层级必须一致,通常为 2 个空格。一个常见的错误是 paths 下的路径键与操作键缩进不一致,导致解析失败。

4.3 路径与操作定义

paths 对象是 OpenAPI 文档的核心,它定义了 API 的所有端点。每个路径键以 / 开头,对应一个 Path Item Object,该对象包含对该路径可执行的所有 HTTP 操作。

4.3.1 路径定义规则

  • 静态路径: 固定字符串,如 /users、/orders
  • 路径参数: 使用花括号 {} 包裹,如 /users/{userId}
  • 路径区分大小写: /Users 和 /users 被视为不同路径
  • 路径末尾斜杠: /users 和 /users/ 在规范中不同,建议统一不带末尾斜杠

4.3.2 操作对象字段

每个 HTTP 方法(get、post、put、delete、patch 等)对应一个 Operation Object,包含以下关键字段:

字段 类型 说明
operationId string 操作的唯一标识符,用于代码生成和文档锚点
summary string 操作的简短摘要,显示在文档列表
description string 操作的详细说明,支持 Markdown
parameters [Parameter Object] 路径参数、查询参数、请求头参数等
requestBody RequestBody Object POST/PUT/PATCH 操作的请求体描述
responses Responses Object 所有可能的 HTTP 状态码响应
tags [string] 用于分组操作的标签列表
security [Security Requirement Object] 操作级别的安全要求

4.3.3 完整路径操作示例

paths:
  /users:
    get:
      operationId: listUsers
      summary: 获取用户列表
      tags: [用户管理]
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: 用户列表
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '400':
          description: 请求参数错误

    post:
      operationId: createUser
      summary: 创建新用户
      tags: [用户管理]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
      responses:
        '201':
          description: 用户创建成功
        '409':
          description: 用户已存在

  /users/{userId}:
    get:
      operationId: getUserById
      summary: 根据 ID 获取用户详情
      tags: [用户管理]
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: 用户详情
        '404':
          description: 用户不存在
最佳实践: 每个操作都应定义 operationId,它不仅是文档锚点,更是 Go 代码生成中函数命名的依据。建议采用 动词+名词 的驼峰命名法,如 listUsers、getUserById、createOrder。

4.4 OpenAPI 3.0 文档结构总览

下面的 SVG 图展示了 OpenAPI 3.0 文档的顶层结构及各核心对象之间的关系:

OpenAPI 3.0 文档顶层结构 OpenAPI 文档 openapi (版本) info (元信息) servers (服务器) paths (路径) components (组件) tags (标签) /users /users/{id} GET (listUsers) POST (createUser) GET (getUserById) PUT (updateUser) schemas parameters responses 核心关系说明 paths 定义 API 端点 → 每个端点包含多个操作 → 操作引用 components 中的 schema/参数/响应 servers 提供基础 URL,info 提供文档元数据,tags 用于分组管理

4.5 参数定义详解

参数是操作定义中最重要的组成部分之一。OpenAPI 3.0 支持四种参数位置:

参数位置 (in) 说明 示例
path URL 路径中的变量,必须 required: true /users/{userId}
query URL 查询字符串参数 ?page=1&limit=20
header HTTP 请求头参数 X-Request-Id
cookie HTTP Cookie 中的参数 sessionId

参数定义示例:

parameters:
  - name: userId
    in: path
    required: true
    description: 用户唯一标识
    schema:
      type: string
      format: uuid
    example: "550e8400-e29b-41d4-a716-446655440000"

  - name: page
    in: query
    required: false
    description: 页码,从 1 开始
    schema:
      type: integer
      minimum: 1
      default: 1

  - name: X-Request-Id
    in: header
    required: false
    description: 请求追踪 ID
    schema:
      type: string
      pattern: "^[a-f0-9]{32}$"

4.6 响应定义与状态码

每个操作必须至少定义一个成功响应。响应对象通过 HTTP 状态码作为键,支持通配符 default 和范围码 2XX、4XX。

responses:
  '200':
    description: 操作成功
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/SuccessResponse'
  '400':
    description: 请求参数错误
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'
  '5XX':
    description: 服务器内部错误
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'
  default:
    description: 未预期的错误
状态码设计建议: 不要只定义 200 和 500。至少为每个操作定义 200/201、400、404(资源不存在)、409(冲突)、500 这五类响应。这能让 API 消费者提前做好错误处理,也是 Go 契约校验的重要依据。

4.7 本章小结

  • OpenAPI 3.0 文档由 openapi、info、servers、paths、components 等顶层对象组成
  • YAML 格式可读性更好,支持注释,是教学和手写文档的首选;JSON 格式工具兼容性更广
  • paths 对象定义 API 端点,每个路径可包含多个 HTTP 操作
  • 操作对象通过 operationId、parameters、requestBody、responses 完整描述 API 行为
  • 参数支持 path、query、header、cookie 四种位置,响应必须覆盖主要状态码
  • 掌握这些核心概念后,下一章将进入实战:使用 Go 编写第一个 OpenAPI 规范文件