4. 路径与操作定义:路径模板、HTTP方法映射、operationId命名规范、参数定义
路径与操作是OpenAPI契约的核心骨架。路径模板定义了资源的访问地址,HTTP方法映射了操作语义,operationId提供了全局唯一的操作标识,而参数定义则规范了客户端与服务端之间的数据交换方式。本章将逐一拆解这些要素的设计原则与治理规则。
4.1 路径模板设计
路径模板使用大括号 {} 表示路径参数,支持静态段与动态段的组合。设计时应遵循以下原则:
- 资源导向:路径应以名词复数形式表示资源,如
/users、/orders。 - 层级清晰:子资源通过嵌套路径表达,如
/users/{userId}/orders。 - 避免动词:操作语义由HTTP方法承载,路径中不应出现
/createUser或/deleteOrder。 - 版本管理:建议在路径前缀中加入版本号,如
/v1/users。
路径模板示例:
该路径清晰表达了“组织下的项目中的任务”这一资源层级关系。
/v1/organizations/{orgId}/projects/{projectId}/tasks
该路径清晰表达了“组织下的项目中的任务”这一资源层级关系。
4.2 HTTP方法映射
每个路径可对应一个或多个HTTP方法,每个方法代表一种操作语义。标准映射关系如下:
| HTTP方法 | 操作语义 | 幂等性 | 请求体 | 典型场景 |
|---|---|---|---|---|
| GET | 查询/读取 | 是 | 无 | 获取资源列表或单个资源 |
| POST | 创建/触发 | 否 | 有 | 创建新资源、提交命令 |
| PUT | 全量替换 | 是 | 有 | 更新整个资源 |
| PATCH | 部分更新 | 否 | 有 | 修改资源的部分字段 |
| DELETE | 删除 | 是 | 无 | 移除指定资源 |
避坑提示:不要将POST用于查询操作,也不要用GET执行状态变更。违反HTTP语义映射会导致API难以理解和维护,破坏契约的直观性。
4.3 operationId命名规范
operationId 是每个操作的全局唯一标识符,在代码生成、日志追踪、文档索引中起关键作用。命名规范如下:
- 动词+名词:使用驼峰命名,如
getUserById、createOrder。 - 唯一性:整个API规范中不可重复,即使路径不同。
- 语义明确:避免模糊命名,如
doSomething、process。 - 与HTTP方法对齐:GET对应
get、POST对应create、PUT对应update、PATCH对应patch、DELETE对应delete。
推荐模式:
示例:
{httpMethod}{ResourceName}[{By|With}{Qualifier}]
示例:
getOrdersByStatus、updateUserProfile、deleteProject
4.4 参数定义:path / query / header / cookie
OpenAPI 3.x 支持四种参数位置,每种位置有特定的使用场景和约束。以下表格对比了各参数类型:
| 参数位置 | 绑定方式 | 是否必填 | 序列化风格 | 典型用途 |
|---|---|---|---|---|
| path | 路径模板变量 | 是 | simple | 资源标识符(ID、Slug) |
| query | URL问号后 | 按需 | form / spaceDelimited / pipeDelimited / deepObject | 过滤、排序、分页、搜索 |
| header | HTTP头部 | 按需 | simple | 认证令牌、内容协商、请求ID |
| cookie | Cookie头部 | 按需 | form | 会话标识、持久化状态 |
4.4.1 路径参数(path)
路径参数是资源定位的核心,必须出现在路径模板中。定义时需注意:
- 必填性:路径参数默认必填,不可设置
required: false。 - 类型约束:应明确指定
schema类型,如integer、string,并配合format或pattern做格式校验。 - 命名一致性:路径参数名应与资源模型中的字段名保持一致。
paths:
/users/{userId}:
get:
operationId: getUserById
parameters:
- name: userId
in: path
required: true
schema:
type: integer
format: int64
minimum: 1
description: 用户唯一标识
4.4.2 查询参数(query)
查询参数用于过滤、排序、分页等非资源标识的场景。设计要点:
- 可选优先:查询参数尽量设为可选,避免强制客户端传递。
- 分页标准化:统一使用
page、size或offset、limit参数名。 - 数组参数:使用
style: form和explode: true支持多值过滤。
parameters:
- name: status
in: query
required: false
schema:
type: array
items:
type: string
enum: [active, inactive, archived]
style: form
explode: true
description: 按状态过滤,可传多个值
4.4.3 头部参数(header)
头部参数适合传递元数据、认证信息、请求追踪标识。注意事项:
- 避免业务数据:header不应承载业务核心参数,仅用于协议级信息。
- 标准化命名:使用连字符分隔,如
X-Request-Id、Authorization。 - 敏感信息:认证令牌应使用
Authorization头,而非自定义header。
parameters:
- name: X-Request-Id
in: header
required: true
schema:
type: string
format: uuid
description: 客户端生成的请求追踪ID,用于日志关联
4.4.4 Cookie参数(cookie)
Cookie参数用于会话管理和持久化状态,在微服务架构中应谨慎使用:
- 无状态优先:优先使用header传递令牌,而非cookie。
- 安全属性:若使用cookie,应在描述中注明
HttpOnly、Secure、SameSite等属性。 - 避免敏感数据:cookie中不应存储明文敏感信息。
parameters:
- name: session_id
in: cookie
required: false
schema:
type: string
pattern: '^[a-zA-Z0-9]{32}$'
description: 会话标识,用于维持用户登录状态
4.5 路径与操作定义流程
以下SVG图展示了从资源识别到完整操作定义的标准化流程:
4.6 参数定义常见反模式
在实际API设计中,以下反模式应严格避免:
| 反模式 | 错误示例 | 正确做法 | 影响 |
|---|---|---|---|
| 路径参数放查询语义 | /users/filter/active |
/users?status=active |
破坏资源层级,难以扩展 |
| operationId重复 | 两个GET都叫 getList |
getUsers、getOrders |
代码生成冲突,文档混乱 |
| header承载业务参数 | X-User-Name 作为必填头 |
放入path或query | 违反HTTP语义,增加调用复杂度 |
| cookie存储敏感数据 | cookie中放明文密码 | 使用session token | 安全漏洞 |
4.7 参数序列化风格选择
OpenAPI 3.x 支持多种序列化风格,选择合适的风格对客户端兼容性至关重要。以下SVG图展示了不同参数位置的推荐序列化策略:
最佳实践:对于数组类型的query参数,始终使用
style: form 和 explode: true,这样客户端可以传递 ?ids=1&ids=2&ids=3,兼容性最好。
4.8 本章小结
路径与操作定义是OpenAPI契约设计的基石。路径模板要资源导向、层级清晰;HTTP方法映射必须严格遵循语义;operationId 需全局唯一且命名规范;参数定义要区分path/query/header/cookie四种位置,并选择合适的序列化风格。遵循这些规范,才能构建出可读、可维护、可自动化的API契约。