网络协议
HTTP 与接口设计基础
理解请求方法、状态码、错误结构、缓存与接口契约之间的关系。
HTTP 语义
HTTP 是无状态的应用层协议。无状态并不是服务器不能保存数据,而是每个请求都应携带完成当前交互所需的信息,服务端不能假设某条连接天然继承了上一条连接的上下文。
接口设计首先要明确资源、操作和结果。URI 用来定位资源,请求方法表达操作意图,状态码描述处理结果,消息正文承载具体数据。把这些职责混在一起,会让客户端只能依赖模糊文本判断结果。
请求方法
GET 通常用于读取,POST 常用于提交新处理,PUT 适合按已知标识整体创建或替换,PATCH 用于部分修改,DELETE 表达删除意图。方法名称不能自动保证安全性,服务端仍需执行身份、权限和参数检查。
安全方法原则上不应改变服务端状态;幂等方法重复执行时,应产生与执行一次相同的预期效果。这里描述的是协议语义,不代表网络中只会发送一次。
状态码
| 范围 | 含义 | 常见用途 |
|---|---|---|
| 2xx | 请求已被成功处理 | 读取成功、创建完成、无正文返回 |
| 3xx | 需要重定向或使用缓存结果 | 资源位置变化、条件请求未修改 |
| 4xx | 请求本身不能按当前形式处理 | 字段错误、身份无效、资源不存在、请求过多 |
| 5xx | 服务端暂时或内部异常 | 依赖不可用、处理超时、内部错误 |
状态码应与机器可读的错误结构配合使用。客户端不应通过中文提示文本推断错误类型。
错误结构
RFC 9457 定义了用于 HTTP API 的问题详情格式。常见字段包括 type、title、status、detail 和 instance。统一结构有利于客户端分类处理,也能减少每个接口自行设计错误格式的差异。
{
"type": "https://example.test/problems/invalid-field",
"title": "请求字段不符合要求",
"status": 400,
"detail": "timestamp 超出允许范围",
"instance": "/requests/01J..."
}
返回内容不应包含堆栈、数据库语句、内部路径或密钥信息。详细诊断数据应写入受控日志,并通过请求编号关联。
缓存
HTTP 缓存可以减少重复传输,但涉及实时状态的接口需要谨慎设置。Cache-Control 用于表达缓存策略,ETag 和条件请求可帮助客户端判断资源是否变化。
不能仅因为使用了 GET 就默认允许共享缓存。响应是否可缓存,还要考虑授权信息、数据时效、用户隔离和中间代理行为。
接口文档
接口文档应明确请求方法、路径、字段类型、是否必填、长度限制、时间格式、状态码、错误结构和重试条件。OpenAPI 规范可用机器可读格式描述接口,便于生成文档、测试和客户端代码。
接口发生兼容性变化时,应通过版本规则或新增字段渐进演进。已有字段的含义、类型和状态码不应在没有版本边界的情况下突然改变。