JSON、表单与图片接口的响应设计规范:先定形状,再定字段
一句话回答
响应设计的核心是让客户端先判断响应类型与成败,再读业务字段。错误体应统一为可判定字段并与状态码一致;成功体按 Content-Type 分流,图片接口需避免把错误当图片返回;新增字段要向后兼容。具体平台的实现细节需以官方文档为准。
响应设计规范要解决的,是让客户端在很少依赖业务文档的情况下回答四个问题:这条响应是什么媒体类型、成功了没有、失败能不能重试、能不能缓存。字段怎么命名是次要的。下文是通用工程建议,不针对某个平台的既有实现;API.PLUS 的具体响应字段与错误码表待核实,需以其官方文档为准,本文未调用任何端点。
一、先定响应契约要回答的四个问题#
- 媒体类型:由
Content-Type声明,客户端据此选择解析器,不能靠 URL 后缀猜。 - 成败判定:HTTP 状态码与响应体中的错误标记必须一致,不能出现 200 包裹业务失败的歧义,也不能 4xx 配一个空的 body。
- 可重试性:限流、超时类失败要能让客户端机器判定,而不是解析自然语言消息。
- 可缓存性:用
Cache-Control、ETag表达,避免客户端自行假设。
二、错误体统一:只保留可判定的字段#
错误响应的价值在于可被程序判断,因此字段应少而稳定。一个常见骨架包含:稳定的机器可读 code、面向人的 message、用于排障关联的 request_id、以及可选的 retryable 与重试等待时间。堆栈、SQL、内部主机名不应出现在响应体中。
以下为未执行的示例,仅演示形状,字段名与取值均为占位:
{
"error": {
"code": "RATE_LIMITED",
"message": "请求过于频繁",
"request_id": "req_demo_0001",
"retryable": true,
"retry_after_seconds": 30
}
}
关键约束是:错误体永远是可解析的结构化数据,即使原始请求是表单提交或图片上传。否则客户端在失败路径上要维护第二套解析逻辑。
三、成功体分流:按 Content-Type 区分,不按路径区分#
| 响应类型 | Content-Type | body | 客户端第一步 |
|---|---|---|---|
| 结构化数据 | application/json | JSON 对象 | 校验顶层形状 |
| 表单提交结果 | JSON 或 303 跳转 | 与 JSON 接口一致 | 先看状态码 |
| 图片 | image/png 等具体类型 | 二进制字节 | 看状态码与 Content-Type,再解码 |
表单与 JSON 两种入口应返回同构的错误体,资源创建成功则返回 201 并带 Location。这样同一资源的客户端只需一套错误处理。
四、图片接口:不要把一个 JSON 错误当图片返回#
Content-Type必须是具体的图片类型,而不是application/octet-stream或笼统的image/*。- 失败时返回非 2xx 状态码,body 为 JSON 错误体;客户端在把字节交给解码器之前先判断状态码与媒体类型。
- 随图返回的元信息(图片标识、尺寸、来源)宜放在响应头或单独的 JSON 接口中,不要混入二进制流。
- 对可变图片使用
ETag与条件请求,避免客户端反复拉取同一份字节。
五、演进边界#
新增字段必须是可选的;不删除已发布字段,不改变字段语义;枚举新增取值时,客户端应有默认分支而不是直接抛错。这三条决定了响应体能否长期兼容。
需要强调的限制:本文不提供任何平台的字段清单、错误码表或性能数据;接入前应核对目标接口的实际响应形状与错误码,并保留一份契约样本用于回归比对。