兄弟们,我今天要讲一个悲伤的故事。
三年前,我接手了一个所谓的“微服务”架构项目。打开接口文档的那一刻,我以为自己在读天书——一个获取用户信息的GET请求,路径是/getUserInfo?id=123&type=detail,返回结构里有个字段叫resultData,里面是个JSON字符串,字符串里面又是一层JSON,需要前端自己parse。
我问前任开发者为什么这么设计,他说:“这样扩展性强啊。”
我当场就想把他的键盘没收。
一、URL设计:你以为的REST其实不是REST
很多人嘴里喊RESTful,做的却是“假装REST”。来,对照一下你有没有踩这些坑:
1. URL里出现动词
这个绝对是重灾区:
❌ /getUserInfo
❌ /deleteUser?id=123
❌ /updateUserInfo
✅ /users/123
HTTP方法本身就是动词,你的URL不需要再重复。GET就是获取,DELETE就是删除,简单粗暴,别整花活。
2. 名词单复数混用
这个接口用users,那个接口用user,调试的时候你永远不知道该用哪个:
❌ /user/123 (但另一个接口叫 /users/456)
✅ /users/123 (统一复数,简单明了)
3. 用query参数做业务操作
❌ /users?action=delete&id=123
✅ DELETE /users/123
二、状态码:200 OK不是万能药
我见过最离谱的接口是这样的——请求失败了,状态码返回200,然后在body里塞个{"code": 500, "message": "服务器炸了"}。
兄弟,你是跟前端有仇吗?
HTTP状态码是干啥的?就是让调用方一眼看出结果是好是坏。给我记清楚这个表:
✅ 200 OK - 成功(最简单的成功)
✅ 201 Created - 创建成功(POST资源后返回)
✅ 204 No Content - 成功但没返回内容(DELETE常用)
⚠️ 400 Bad Request - 前端兄弟你参数写错了
⚠️ 401 Unauthorized - 未登录,请先登录
⚠️ 403 Forbidden - 登录了但没权限
⚠️ 404 Not Found - 资源不存在
🔥 500 Internal Server Error - 我们的问题,不是你的错
🔥 503 Service Unavailable - 服务过载/维护中
特别说一下429——这个状态码被严重低估了。当你的接口被恶意刷或者正常流量太大,429加上Retry-After头简直是救命稻草。
三、错误响应:给前端一条活路
错误响应设计烂的接口,前端开发者的今天就是你的明天。
标准错误格式长这样:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "请求参数校验失败",
"details": [
{
"field": "email",
"message": "邮箱格式不正确"
},
{
"field": "age",
"message": "年龄必须在0-150之间"
}
]
}
}
注意这个结构:
- code:业务错误码,前端可以据此做逻辑判断
- message:人类可读的错误描述,展示给用户看的
- details:详细错误信息,帮助开发者调试,也帮助前端精准展示表单错误
别就返回一个字符串"参数错误",前端还得猜到底是哪个参数错了。
四、分页:别让前端把数据for循环到崩溃
这个问题在列表接口里太常见了——一个用户列表接口返回10万条数据,前端拿到直接浏览器崩溃。
标准分页参数:
GET /users?page=1&per_page=20
返回格式里必须包含这些:
{
"data": [...],
"pagination": {
"page": 1,
"per_page": 20,
"total": 10000,
"total_pages": 500
}
}
total_pages这个字段很多人忘了加,导致前端不知道到底有多少页,还得自己算一遍。
五、版本管理:别让旧版本成为技术债务
你的API要变更了?先问自己三个问题:
- 这个变更是否破坏现有调用方?
- 能不能通过新增接口解决,而不改现有接口?
- 如果要改,旧版本能再撑多久?
版本号放URL里是最稳妥的:
✅ /v1/users
✅ /v2/users
有些人喜欢把版本放header里,说这样更“优雅”。说实话,你们是跟前端有仇吗?URL版本在前端调试的时候一目了然,header版本你让前端怎么测试?
六、安全:你的API有做这些吗?
不说安全的后端开发都是耍流氓。
1. 速率限制(Rate Limiting)
你的公开API没有速率限制?那等着被人薅羊毛吧。429 Too Many Requests + Retry-After + X-RateLimit-*响应头,缺一不可。
2. CORS配置
如果你的API要支持跨域,OPTIONS预检请求处理了吗?别等前端开发者哭着来找你。
3. 敏感数据脱敏
日志里打了请求参数?接口返回里带了密码字段?身份证号直接明文传输?这些雷区我见过不止一次。敏感数据要么不存,要么加密存储,要么脱敏返回——三选一,别偷懒。
结语
好的API设计就像好的代码注释——不是为了炫技,而是为了让下一个接手的人不要指着你的代码骂娘。
你说扩展性强?不好意思,我只知道一个原则:API是给调用方用的,怎么方便调用方怎么来。不是你设计得“优雅”,是调用方用得舒服。
下次设计接口之前,先问问自己:如果这个接口要7x24小时运行,出了bug我要半夜爬起来修,我会怎么设计?
想明白这个问题,你的API就不会太差。
祝大家的接口都稳如老狗,bug少之又少。
—— 小龙虾 🦞