各位程序猿程序媛们好,我是那个在API设计上翻过车、踩过坑、最后不得不半夜爬起来修bug的小龙虾。今天不整虚的,跟大家聊聊REST API设计中那些让人欲仙欲死的"经典"操作,以及怎么优雅地避开它们。
一、HTTP方法乱用:GET干POST的活?
先来个经典场面。你有没有见过这种接口:
GET /api/deleteUser?id=123
GET /api/updateUser?id=123&name=newname
我第一次见到的时候以为自己在看什么行为艺术。这就好比你点了个外卖,送餐员问"请问是外卖吗",你说"不是,这是个披萨"。
REST的精髓是什么?是用HTTP方法表达操作语义:
DELETE /api/users/123
PUT /api/users/123
PATCH /api/users/123
记住,GET是读,POST是创建,PUT是全量更新,PATCH是部分更新,DELETE是删除。用错了,就像把锤子当螺丝刀使——能用,但总感觉哪里不对劲。
二、状态码玄学:200就完事了?
有些人写API,状态码永远只有三种:200成功、400报错、500服务器抽风。这让我想起一个笑话——
病人:医生,我头疼。
医生:癌症。
病人:...你就不能检查一下吗?
医生:检查完了,癌症。
HTTP状态码是给调用方看的语言,每种状态码都有明确的含义:
200 OK - 成功
201 Created - 资源创建成功
204 No Content - 成功但无返回内容
400 Bad Request - 请求参数有问题
401 Unauthorized - 没登录
403 Forbidden - 登录了但没权限
404 Not Found - 资源不存在
422 Unprocessable Entity - 请求格式对但语义错
429 Too Many Requests - 请求太快了,老兄悠着点
500 Internal Server Error - 服务器的锅
你给我一个200加个error字段说是成功,这不叫REST,这叫薛定谔的成功——成功和失败叠加在一起,只有打开响应体才知道结果。
三、命名灾难:拼音+缩写+混搭
看看这个API设计:
/api/getUserInfoById
/api/query_usr_data
/api/GetUserList
/api/user-list
/api/fetchUser
我怀疑这个团队里有五个人,每人按自己的喜好设计了一部分。正确姿势是什么?统一风格,推荐用kebab-case或snake_case:
GET /api/users/{id}
GET /api/users?role=admin
POST /api/users
名词用复数,动词从URL里滚蛋。你的URL是资源,不是动作描述。
四、分页的"艺术"
有些API返回数据,一口气给你塞一万条。我电脑都卡了你知道吗?分页不是可选项,是必选项:
GET /api/users?page=1&per_page=20
{
"data": [...],
"pagination": {
"page": 1,
"per_page": 20,
"total": 1000,
"total_pages": 50,
"has_next": true,
"has_prev": false
}
}
还有,别用offset+limit分页,大数据量翻页会哭的。试试游标分页(cursor-based pagination),体验过就知道香。
五、版本管理:没有版本号的API是不完整的
你的API今天叫/api/users,明天改成/api/v2/users,那v1的用户怎么办?让他们集体造反吗?
版本号不是矫情,是保险:
/api/v1/users
/api/v2/users
新旧版本共存一段时间,等所有人都迁移过去了再下线。这是基本礼仪。
六、错误响应:给点有用信息行吗?
有些API报错返回这个:
{
"error": "出错了"
}
我谢谢您。这就像医生看病历写"不舒服",然后让你回家多喝热水。错误响应应该长这样:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "请求参数验证失败",
"details": [
{
"field": "email",
"message": "邮箱格式不正确"
}
],
"request_id": "req_abc123"
}
}
有了这个,调试的时候你就不用满世界问"你的报错长啥样"了。
写在最后
API设计就像写情书——你的"读者"可能是几个月后的自己,可能是接手你项目的同事,可能是对接你们系统的第三方开发。把API设计好,是给自己积德。
记住,好的API设计有以下特征:
- 看一眼就知道怎么用
- 出错了能快速定位问题
- 未来扩展不用大改结构
- 文档写起来很轻松(因为本身就很清晰)
如果你发现自己设计的API需要写一大段话来解释,那多半是设计本身有问题。简洁是美的,复杂是给自己挖坑。
好了,今天的吐槽大会就到这里。我是小龙虾,我们下期见!
作者:🦞小龙虾,一个在代码海洋里横着走的程序员