4. 路径与操作定义:路径模板、HTTP方法映射、operationId、参数定义、请求体定义
路径与操作是OpenAPI契约的核心骨架。一个API端点由路径模板和HTTP方法共同唯一标识,而operationId、参数定义和请求体定义则精确描述了该操作的行为与数据约束。本章将逐一拆解这些要素,并展示它们在契约校验中的关键作用。
4.1 路径模板:从静态路径到动态参数化
路径模板使用花括号 {} 声明路径参数,允许客户端在请求时传入动态值。路径模板必须遵循以下规则:
- 静态部分:固定字符串,如
/users、/orders。 - 路径参数:用
{paramName}表示,参数名必须与parameters中定义的name一致。 - 不允许重复:同一路径模板中不能出现同名路径参数。
- 不允许连续花括号:
{a}{b}非法,必须用分隔符如{a}/{b}。
契约校验要点:路径模板中的参数名必须与 parameters 段中 in: path 的参数 name 完全匹配,且该参数必须标记为 required: true。
paths:
/users/{userId}/orders/{orderId}:
get:
parameters:
- name: userId
in: path
required: true
schema:
type: string
- name: orderId
in: path
required: true
schema:
type: integer
responses:
'200':
description: 成功返回订单详情
4.2 HTTP方法映射:操作与语义的绑定
每个路径下可定义多个HTTP方法,每个方法对应一个操作对象。OpenAPI 3.0支持的方法包括:get、post、put、patch、delete、head、options、trace。方法名必须小写。
| HTTP方法 | 典型语义 | 是否允许请求体 | 幂等性 |
|---|---|---|---|
| GET | 查询资源 | 不允许 | 是 |
| POST | 创建资源 | 允许 | 否 |
| PUT | 全量替换资源 | 允许 | 是 |
| PATCH | 部分更新资源 | 允许 | 否 |
| DELETE | 删除资源 | 不允许 | 是 |
常见错误:在 GET 或 DELETE 操作中定义 requestBody,契约校验会直接报错。同样,在 POST 或 PUT 中遗漏 requestBody 也可能导致校验失败(除非该操作确实不需要请求体)。
4.3 operationId:操作的唯一标识符
operationId 是操作对象的可选但强烈推荐的字段,用于在工具链中唯一标识一个操作。它必须满足以下约束:
- 全局唯一:在整个API规范中,所有 operationId 不能重复。
- 命名规范:通常采用驼峰命名法,如
getUserById、createOrder。 - 用途:代码生成器使用 operationId 生成方法名;契约测试工具用它定位具体操作。
paths:
/users/{userId}:
get:
operationId: getUserById
summary: 根据用户ID获取用户信息
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: 用户对象
最佳实践:operationId 应使用动词+名词的格式,清晰表达操作意图。避免使用模糊名称如
doSomething 或 process。
4.4 参数定义:query、path、header、cookie
参数定义是契约校验的高频校验点。每个参数必须包含 name、in、schema 三个核心字段。in 决定了参数的位置,不同位置的参数有不同的校验规则。
| 参数位置 (in) | 示例 | 序列化方式 | 是否必须声明 required |
|---|---|---|---|
| path | /users/{id} |
简单值 | 必须为 true |
| query | ?page=1&size=20 |
form / deepObject | 可选,默认 false |
| header | X-Request-Id: abc |
simple | 可选,默认 false |
| cookie | Cookie: sessionId=xyz |
form | 可选,默认 false |
parameters:
- name: page
in: query
required: false
schema:
type: integer
minimum: 1
default: 1
- name: Authorization
in: header
required: true
schema:
type: string
pattern: '^Bearer .+$'
契约校验规则:
1. path 参数必须 required: true,否则校验失败。
2. query 参数如果 required: true,则请求必须携带该参数。
3. header 参数名不区分大小写,但规范中建议使用首字母大写的驼峰格式。
4. cookie 参数较少使用,但支持结构化数据。
1. path 参数必须 required: true,否则校验失败。
2. query 参数如果 required: true,则请求必须携带该参数。
3. header 参数名不区分大小写,但规范中建议使用首字母大写的驼峰格式。
4. cookie 参数较少使用,但支持结构化数据。
4.5 请求体定义:requestBody 的结构与约束
请求体定义仅在支持请求体的HTTP方法(POST、PUT、PATCH)中使用。OpenAPI 3.0使用 requestBody 对象替代了2.0中的 body 参数,提供了更灵活的内容协商能力。
请求体定义包含三个核心部分:
- description:对请求体的文字描述,可选但推荐。
- required:布尔值,标识请求体是否为必须。默认 false。
- content:一个映射,键为媒体类型(如
application/json),值为媒体类型对象,其中包含schema定义。
requestBody:
description: 创建用户所需的用户信息
required: true
content:
application/json:
schema:
type: object
required:
- username
- email
properties:
username:
type: string
minLength: 3
maxLength: 50
email:
type: string
format: email
age:
type: integer
minimum: 0
maximum: 150
契约校验陷阱:
1. 如果 requestBody 标记为 required: true,但请求未携带请求体,校验失败。
2. content 中至少需要定义一个媒体类型,空 content 对象会导致校验错误。
3. 如果定义了多个媒体类型,客户端必须发送与其中之一匹配的 Content-Type 头。
1. 如果 requestBody 标记为 required: true,但请求未携带请求体,校验失败。
2. content 中至少需要定义一个媒体类型,空 content 对象会导致校验错误。
3. 如果定义了多个媒体类型,客户端必须发送与其中之一匹配的 Content-Type 头。
4.6 路径与操作的综合校验流程
契约测试工具在验证路径与操作时,通常按以下步骤执行:
- 路径匹配:将实际请求路径与路径模板进行模式匹配,提取路径参数值。
- 方法校验:检查HTTP方法是否在路径下定义,未定义则返回405 Method Not Allowed。
- 参数校验:逐一校验 query、header、path、cookie 参数的类型、格式、是否必需。
- 请求体验证:如果操作定义了 requestBody,校验请求体的媒体类型和 schema 约束。
- operationId 映射:将校验通过的操作映射到对应的 operationId,用于后续的响应校验和文档生成。
实战建议:在编写契约测试用例时,建议为每个操作至少准备三组测试数据:
1. 正常用例:所有必需参数和请求体字段均合法。
2. 边界用例:参数值在边界附近(如最小值、最大值、空字符串)。
3. 异常用例:缺少必需参数、类型错误、格式不合法。
1. 正常用例:所有必需参数和请求体字段均合法。
2. 边界用例:参数值在边界附近(如最小值、最大值、空字符串)。
3. 异常用例:缺少必需参数、类型错误、格式不合法。