3. RESTful API 基础回顾:HTTP 方法、状态码、REST 设计原则、资源路径命名规范
在进入授权测试与接口兼容性校验之前,必须夯实 RESTful API 的基础。REST(Representational State Transfer)是一种架构风格,而非协议。它利用 HTTP 协议的特性,将后端资源抽象为统一接口。本章从四个核心维度展开:HTTP 方法、状态码、设计原则与资源路径命名。
3.1 HTTP 方法与 CRUD 映射
RESTful API 的核心是将对资源的操作映射到标准的 HTTP 方法上。每个方法对应一种原子操作,这是接口兼容性校验的起点。
| HTTP 方法 | CRUD 操作 | 幂等性 | 安全性 | 典型响应状态码 |
|---|---|---|---|---|
| GET | 读取(Read) | 是 | 是 | 200 OK |
| POST | 创建(Create) | 否 | 否 | 201 Created |
| PUT | 整体替换(Update) | 是 | 否 | 200 OK / 204 No Content |
| PATCH | 部分更新(Partial Update) | 否 | 否 | 200 OK / 204 No Content |
| DELETE | 删除(Delete) | 是 | 否 | 204 No Content |
运维提示: 幂等性是接口兼容性校验的关键指标。在重试机制中,GET、PUT、DELETE 可以安全重试,而 POST 必须引入去重令牌(Idempotency-Key)防止重复创建。
3.2 HTTP 状态码:语义化响应
状态码是客户端判断请求结果的直接依据。在授权测试中,401 Unauthorized 与 403 Forbidden 的区分至关重要。
- 2xx 成功
200 OK:GET、PUT、PATCH 成功返回资源。201 Created:POST 成功创建资源,响应头应包含Location。204 No Content:DELETE 成功,或 PUT/PATCH 无需返回 body。
- 3xx 重定向
301 Moved Permanently:资源 URI 已变更,客户端应更新缓存。304 Not Modified:配合ETag或If-Modified-Since使用。
- 4xx 客户端错误
400 Bad Request:请求体格式错误或参数校验失败。401 Unauthorized:缺少身份凭证或凭证无效。403 Forbidden:身份已认证,但无操作权限。404 Not Found:资源不存在。409 Conflict:资源当前状态与请求冲突(如版本冲突)。422 Unprocessable Entity:语义错误,如必填字段缺失。429 Too Many Requests:触发限流。
- 5xx 服务端错误
500 Internal Server Error:通用服务端异常。502 Bad Gateway:上游服务不可用。503 Service Unavailable:服务过载或维护中。504 Gateway Timeout:上游服务超时。
授权测试陷阱: 许多 API 在 Token 过期时错误地返回
403 Forbidden 而非 401 Unauthorized。正确的语义是:401 表示“你是谁?”,403 表示“知道你是谁,但不行”。在兼容性校验中,必须严格区分这两个状态码。
3.3 REST 设计原则
REST 的六大约束是接口长期可维护的基石。以下原则直接指导授权测试用例的设计:
- 客户端-服务端分离(Client-Server):关注点分离,客户端不关心数据存储。
- 无状态(Stateless):每个请求包含所有必要信息,服务端不保存会话状态。授权信息必须放在请求头中。
- 可缓存(Cacheable):响应隐式或显式标记为可缓存或不可缓存。GET 请求应支持
Cache-Control。 - 统一接口(Uniform Interface):资源通过 URI 标识,通过表述(Representation)操作资源,自描述消息,HATEOAS(超媒体作为应用状态引擎)。
- 分层系统(Layered System):客户端无法直接感知是否与端服务器或中间代理通信。
- 按需代码(Code on Demand,可选):服务端可传输可执行脚本(如 JavaScript)。
工程落地: 在微服务网关层,无状态原则要求 Token 必须自包含(如 JWT),不能依赖服务端 Session。在兼容性校验中,需验证每个请求是否独立携带完整的 Authorization 头。
3.4 资源路径命名规范
资源路径是 API 的门面。统一的命名规范能降低授权规则的配置复杂度,减少误配风险。
| 规范 | 正确示例 | 错误示例 | 说明 |
|---|---|---|---|
| 使用名词复数 | /api/v2/users |
/api/v2/getUser |
资源是实体,不是动作 |
| 层级关系用斜杠 | /users/{id}/orders |
/users/{id}/getOrders |
子资源通过路径嵌套表达 |
| 查询参数用于过滤 | /orders?status=active |
/orders/active |
路径标识资源,参数限定集合 |
| 小写字母 + 连字符 | /user-profiles |
/userProfiles / /user_profiles |
连字符提高可读性 |
| 版本号放在前缀 | /v1/users |
/users/v1 |
版本号应尽早路由 |
| 避免动词 | /users/{id}/activate |
/users/{id}/activateUser |
动词可接受,但需保持极简 |
3.5 RESTful API 请求-响应生命周期
下图展示了从客户端发起请求到服务端响应的完整流程,重点标注了授权校验与状态码决策点。
3.6 路径命名与授权粒度的关系
资源路径的结构直接影响授权策略的配置粒度。常见的授权模型与路径模式对应如下:
- 粗粒度(路径级):
/api/v2/admin/*→ 仅管理员可访问。 - 中粒度(资源级):
/api/v2/users/{userId}→ 用户只能访问自己的资源。 - 细粒度(字段级):
/api/v2/users/{userId}/profile→ 结合 Scope 限制可读字段。
兼容性校验清单:
- 检查路径是否遵循复数名词 + 连字符规范。
- 验证版本号是否在路径最前(
/v1/而非/api/v1/或/api/)。 - 确认所有路径参数(Path Variable)使用花括号
{id}而非冒号:id。 - 测试
POST创建资源后,Location头是否指向新资源 URI。 - 验证
GET集合资源是否支持?page=1&size=20分页参数。
3.7 常见反模式与避坑指南
| 反模式 | 问题描述 | 正确做法 |
|---|---|---|
| 在 GET 请求中使用 Body | 部分客户端或网关不支持 GET 携带 Body | 使用查询参数传递过滤条件 |
| 返回 200 并在 Body 中放错误码 | 破坏 HTTP 语义,网关无法统一处理 | 使用 4xx/5xx 状态码 + 标准错误结构 |
| 路径中包含动词(/getUsers) | 混淆资源与操作,违反 REST 原则 | 使用 HTTP 方法表达操作(GET /users) |
| 忽略 HATEOAS | 客户端硬编码 URI,升级困难 | 在响应中包含 links 字段 |
| 版本号放在查询参数(?v=1) | 缓存失效困难,路由不明确 | 版本号放在路径前缀(/v1/) |