为什么制定规范
统一公司HTTP对外API接口输出标准,消除多技术栈、多业务服务之间 接口返回格式差异,降低前后端联调成本,方便错误处理、日志排查与自动化测试,有以下好处:
- 降低前端对接成本:一套解析逻辑即可对接全部后端接口,无需为不同服务做差异化适配,减少联调bug。
- 统一异常与错误处理:标准化业务错误码、提示信息,便于前端统一弹窗提示、错误埋点统计。
- 便于问题排查定位:统一requestId链路追踪,结合日志可以快速定位接口故障。
- 提升接口可读性与一致性:对分页、空值、时间、ID、敏感字段做统一约束,减少理解歧义。
- 便于网关、测试、监控系统接入:标准化报文有利于自动化测试、接口监控统一解析处理。
一、统一响应体格式
成功响应
成功时 HTTP 状态码是 200,业务 code 也是 200:
{
"code": 200,
"msg": "操作成功",
"data": {},
"requestId": "uuid-xxxxxx"
}
失败响应
业务异常,HTTP状态码依旧 200,业务 code 标识错误
{
"code": 40001,
"msg": "用户名密码错误",
"data": null,
"requestId": "uuid-xxxxxx"
}
字段说明
| 字段 | 说明 |
|---|---|
| code | 业务状态码,200代表业务成功;不等于HTTP status_code |
| msg | 人类可读提示,给前端展示;错误场景直接返回给用户 |
| data | 业务数据;成功返回对象/数组,失败固定为null,不返回多余字段 |
| requestId | 请求唯一ID,链路追踪,日志排查必带 |
约定
- 无论成功失败,结构体字段不能缺失;data失败必须为
null,不要省略key - HTTP状态码尽量统一用
200,业务错误全部走code;鉴权失败可返回401,权限不足403 - requestId 从请求头
X‑Request‑Id获取,没有则生成UUID
二、业务错误码设计规范
码段划分
| 码段 | 含义 |
|---|---|
| 200 | 业务成功 |
| 40xxx | 客户端错误(参数错误、登录失效、业务校验失败) |
| 50xxx | 服务端内部错误(数据库异常、第三方调用失败) |
示例
200 成功
40001 账号密码错误
40002 参数校验失败
40100 token失效/未登录
40300 无操作权限
40400 资源不存在
50001 服务器内部异常
50002 第三方接口调用失败
禁止:直接把原始异常堆栈丢给前端;堆栈只输出到服务端日志。
三、分页接口返回规范
data 里面套分页结构体
{
"code": 200,
"msg": "操作成功",
"data": {
"total": 123,
"pageNum": 1,
"pageSize": 10,
"pages": 13,
"list": [
{"id":1,"name":"xxx"}
]
},
"requestId": "uuid-xxxxxx"
}
字段解释
- pageNum:当前页码,从1开始
- pageSize:每页条数
- total:总条数
- pages:总页数
- list:实际业务数组
查询参数:pageNum:int=1, pageSize:int=10,后端做上限保护,pageSize最大100,防止大查询拖垮数据库。
四、企业开发其它强制规范
- 时间字段。全部返回
datetime字符串,格式:yyyy‑MM‑dd HH,禁止返回对象,禁止返回时间戳混用。
ss - 布尔值:返回true/false,不要用0/1数字代替布尔。
- 空数组:查询无数据返回
[],不要返回null。 - ID:数据库bigint,返回给前端建议转字符串,避免JS丢失精度。
- 安全:接口不要返回密码、salt等敏感字段;pydantic model过滤敏感字段。
- 请求头:透传
X‑Request‑Id,日志打印该ID,方便定位问题。 - openapi文档:所有接口写summary、description,pydantic字段写description,自动生成文档给前端看。
- 不要返回多余字段:数据库字段不要全部直接透传到response,使用输出model做裁剪。
五、不推荐的写法
- ❌ 成功返回
{"code":200,"data":{}},失败返回{"code":400,"msg":"xxx"},data字段缺失,前端解析报错。 - ❌ 异常直接raise HTTPException,返回FastAPI原生格式,前后端两套返回体。
- ❌ 把堆栈信息暴露给前端。
- ❌ http状态码乱用,业务错误返回4xx/5xx http码,前端axios统一拦截混乱。
- ❌ 分页接口list为null,没有返回空数组。