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 文档的顶层结构及各核心对象之间的关系:
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 规范文件