4. OpenAPI/Swagger 规范入门:OpenAPI 3.0 核心结构
OpenAPI 规范(原 Swagger 规范)是业界标准的 RESTful API 接口描述语言。OpenAPI 3.0 版本通过一套结构化的 JSON 或 YAML 文档,完整定义 API 的端点、请求参数、响应格式、认证方式及数据模型。在 Go 后端项目中,使用 OpenAPI 规范作为接口契约,可以实现前后端并行开发、自动化测试与文档生成。
4.1 OpenAPI 3.0 文档顶层结构
一个合法的 OpenAPI 3.0 文档必须包含以下四个顶层字段:openapi、info、paths 和 components。其余字段如 servers、tags、externalDocs 为可选增强。
| 字段名 | 必需 | 类型 | 说明 |
|---|---|---|---|
openapi |
是 | string | 规范版本号,固定为 3.0.3 或 3.0.2 |
info |
是 | Info Object | API 元信息:标题、版本、描述、联系人、许可证 |
paths |
是 | Paths Object | 所有 API 端点的路径与操作定义 |
components |
否 | Components Object | 可复用的 schema、参数、响应、请求体、安全方案等 |
servers |
否 | [Server Object] | API 的基础 URL 列表,支持变量替换 |
tags |
否 | [Tag Object] | 用于对端点进行逻辑分组 |
$ref 引用 components 中的定义,避免在 paths 中重复编写相同的数据结构。这是保持契约整洁的核心手段。
4.2 Info 对象:API 元信息
info 对象提供 API 的基本标识和文档说明。Go 后端团队在发布接口契约时,应在此字段中明确 API 名称、版本号以及维护团队的联系方式。
info:
title: "用户服务 API"
description: "提供用户注册、登录、资料查询与修改功能"
version: "1.0.0"
contact:
name: "后端架构组"
email: "backend@example.com"
license:
name: "Apache 2.0"
url: "https://www.apache.org/licenses/LICENSE-2.0"
| 子字段 | 必需 | 说明 |
|---|---|---|
title |
是 | API 名称,建议与 Go 项目模块名保持一致 |
version |
是 | 遵循语义化版本,如 1.0.0、2.3.1 |
description |
否 | 支持 CommonMark 语法,可包含接口用途与使用场景 |
contact |
否 | 包含 name、email、url,便于问题反馈 |
info.version 与 Git tag 或 CI 构建号绑定,确保每次发布契约时版本号自动更新。
4.3 Paths 对象:端点与操作
paths 是 OpenAPI 文档的核心,以 URL 路径为键,映射该路径下支持的 HTTP 方法(GET、POST、PUT、DELETE 等)。每个操作(Operation Object)包含 parameters、requestBody、responses 等子字段。
paths:
/users:
get:
summary: "获取用户列表"
operationId: "listUsers"
parameters:
- name: page
in: query
schema:
type: integer
default: 1
responses:
'200':
description: "用户列表"
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
post:
summary: "创建新用户"
operationId: "createUser"
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: "创建成功"
content:
application/json:
schema:
$ref: '#/components/schemas/User'
| 操作字段 | 必需 | 说明 |
|---|---|---|
operationId |
否 | 唯一标识,Go 代码生成工具常以此作为函数名 |
parameters |
否 | 路径参数、查询参数、请求头参数 |
requestBody |
否 | POST/PUT/PATCH 操作的请求体描述 |
responses |
是 | 至少定义一个响应,通常包含 200 或 201 |
summary |
否 | 简短描述,用于文档列表展示 |
paths 中直接内联复杂 schema 会导致文档膨胀且难以维护。始终优先使用 $ref 引用 components/schemas 中的定义。
4.4 Components 对象:可复用定义
components 是 OpenAPI 3.0 的复用中心,包含 schemas、parameters、responses、requestBodies、securitySchemes 等子对象。Go 后端团队在此定义数据模型,与 Go 结构体一一对应。
components:
schemas:
User:
type: object
required:
- id
- email
properties:
id:
type: integer
format: int64
email:
type: string
format: email
nickname:
type: string
created_at:
type: string
format: date-time
CreateUserRequest:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
nickname:
type: string
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
| Components 子对象 | 用途 | Go 后端对应 |
|---|---|---|
schemas |
定义数据模型(DTO、VO) | Go struct 定义 |
parameters |
可复用的查询/路径/头参数 | 函数参数或中间件解析 |
responses |
可复用的响应结构 | 统一响应体封装 |
requestBodies |
可复用的请求体定义 | 请求反序列化结构体 |
securitySchemes |
认证方案定义 | JWT/OAuth2 中间件 |
oapi-codegen 工具时,components/schemas 中的每个 schema 会生成对应的 Go 结构体,字段名通过 json tag 映射。务必在 schema 中明确 required 列表,否则生成的 Go 结构体字段会使用指针类型。
4.5 OpenAPI 3.0 文档结构总览
下图展示了 OpenAPI 3.0 文档的顶层结构以及各核心对象之间的引用关系。Go 后端开发者应重点关注 paths 与 components/schemas 之间的 $ref 连接。
4.6 从 Go 结构体到 OpenAPI Schema 的映射规则
在 Go 后端项目中,OpenAPI 的 components/schemas 与 Go 结构体之间存在直接映射关系。下表列出常见 Go 类型与 OpenAPI 类型的对应关系:
| Go 类型 | OpenAPI Schema 类型 | format | 说明 |
|---|---|---|---|
int32 |
integer |
int32 |
32 位整数 |
int64 |
integer |
int64 |
64 位整数,常用于 ID 字段 |
float64 |
number |
double |
双精度浮点数 |
string |
string |
— | 默认字符串 |
time.Time |
string |
date-time |
RFC3339 格式 |
[]T |
array |
— | items 引用 T 的 schema |
map[string]T |
object |
— | additionalProperties 引用 T |
struct{} |
object |
— | properties 列出所有字段 |
oapi-codegen(由 DeepMap 维护)或 ogen 从 OpenAPI 文档生成服务端骨架代码。这些工具严格遵循 components/schemas 中的定义,自动生成 json tag 和验证逻辑。
4.7 最小可用 OpenAPI 3.0 文档示例
以下是一个完整的 OpenAPI 3.0 文档,包含 info、paths 和 components 三个核心部分。Go 后端团队可以以此作为起点,逐步扩展接口定义。
openapi: "3.0.3"
info:
title: "订单服务 API"
version: "1.0.0"
description: "提供订单创建、查询与状态更新接口"
paths:
/orders:
get:
operationId: "listOrders"
summary: "查询订单列表"
parameters:
- name: status
in: query
schema:
type: string
enum: [pending, paid, shipped, cancelled]
responses:
"200":
description: "订单列表"
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Order"
post:
operationId: "createOrder"
summary: "创建新订单"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateOrderRequest"
responses:
"201":
description: "创建成功"
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
components:
schemas:
Order:
type: object
required: [id, user_id, total_amount, status]
properties:
id:
type: integer
format: int64
user_id:
type: integer
format: int64
total_amount:
type: number
format: double
status:
type: string
enum: [pending, paid, shipped, cancelled]
created_at:
type: string
format: date-time
CreateOrderRequest:
type: object
required: [user_id, items]
properties:
user_id:
type: integer
format: int64
items:
type: array
items:
type: object
required: [product_id, quantity]
properties:
product_id:
type: integer
format: int64
quantity:
type: integer
minimum: 1
openapi字段固定版本号,info提供元数据,paths定义端点,components提供复用定义。- 所有复杂数据结构应定义在
components/schemas中,通过$ref引用。 - Go 后端使用
oapi-codegen等工具自动生成代码时,schema 的required列表直接影响生成的 Go 类型是否为指针。 - 保持文档与 Go 代码同步,建议将 OpenAPI 文档纳入版本控制,并在 CI 中校验其合法性。