第4章:HTTP方法与状态码
在模块边界API契约中,HTTP方法和状态码构成了请求-响应交互的核心语义层。方法定义了动作意图,状态码表达了结果语义;两者共同决定了模块间通信的可预测性与自描述性。本章围绕两种元素展开,重点说明如何在契约设计中正确选用方法、解耦错误传递、保持幂等与安全边界。
4.1 HTTP方法语义对比
| 方法 | 语义 | 幂等 | 安全(不修改状态) | 请求体支持 | 典型用途 |
|---|---|---|---|---|---|
| GET | 查询 / 读取资源 | 是 | 是 | 无 | 获取列表、详情 |
| POST | 创建 / 提交处理 | 否 | 否 | 是 | 新增订单、触发动作 |
| PUT | 全量替换 / 更新 | 是 | 否 | 是 | 更新用户配置、重置状态 |
| DELETE | 删除资源 | 是 | 否 | 可选 | 注销账户、移除条目 |
设计原则: 在模块边界处,优先使用幂等方法(GET/PUT/DELETE)以简化重试与补偿逻辑;POST仅用于非幂等操作(如创建、触发异步任务)。方法的选择直接影响了上下游的重试策略和缓存行为。
4.2 状态码分类与语义
状态码按大类分为 2xx 成功、4xx 客户端错误、5xx 服务端错误。在边界契约中,状态码必须精确反映操作结果,避免使用“万能 200”或“万能 500”掩盖业务异常。
| 范围 | 典型码 | 含义 | 模块契约使用场景 |
|---|---|---|---|
| 2xx | 200 OK | 成功,响应体包含结果 | GET查询、POST创建成功返回实体 |
| 201 Created | 资源已创建 | POST新建资源时返回 Location 头 | |
| 204 No Content | 成功,无响应体 | DELETE删除成功、PUT更新成功无需返回 | |
| 4xx | 400 Bad Request | 请求语法错误 / 参数校验失败 | 必填字段缺失、格式错误 |
| 401 Unauthorized | 身份认证失败 | 令牌过期、签名错误 | |
| 403 Forbidden | 授权不足 | 权限不足,但有身份 | |
| 404 Not Found | 资源不存在 | ID无效、路由不存在 | |
| 5xx | 500 Internal Server Error | 未预期的服务端错误 | 数据库崩溃、依赖超时 |
| 503 Service Unavailable | 服务临时不可用 | 过载、熔断、维护 |
避坑提醒: 不要将业务错误(如余额不足)映射为 500;应使用 4xx(如 422 Unprocessable Entity)并附加业务错误码。5xx 只用于服务端内部不可恢复的故障,以便客户端区分重试策略。
4.3 模块边界中的方法与状态数据流
下图展示了一个典型跨模块调用中,方法语义如何触发服务处理,并根据结果返回对应状态码。箭头上的标签表明了幂等性和安全性约束。
4.4 契约定义示例(OpenAPI 3.0)
在模块边界契约文档中,每个操作都必须明确声明方法、请求体和响应状态码。以下片段展示了用户管理模块的API定义:
openapi: 3.0.3
info:
title: 用户模块边界API
version: 1.0.0
paths:
/users/{userId}:
get:
summary: 查询用户详情
parameters:
- name: userId
in: path
required: true
schema: { type: string }
responses:
'200':
description: 成功返回用户对象
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: 用户不存在
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
delete:
summary: 删除用户
responses:
'204':
description: 删除成功,无内容
'404':
description: 用户不存在
/users:
post:
summary: 创建用户
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: 创建成功,返回用户对象
headers:
Location:
schema: { type: string }
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'422':
description: 请求参数校验失败
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
4.5 状态码与错误码的协同策略
单个状态码不足以描述所有业务异常,需配合业务错误码实现细粒度原因传递。推荐规范:
- HTTP头中通过
X-Error-Code或响应体内code字段返回模块级错误标识; - 4xx 状态码 + 业务错误码 → 客户端可针对不同错误码执行不同处理(如重新授权、修正参数);
- 5xx 状态码 + 全局重试标识 → 客户端使用固定退避策略;
- 避免在 2xx 响应体中嵌入错误信息(违反语义化原则)。
契约固化建议: 在模块边界合约中,明确列出每个方法支持的 至少一个成功状态码 和 至少一个错误状态码;禁止声明“default”响应而不给出具体码值。通过代码生成(如 openapi-generator)自动校验状态码覆盖度。