各位接口爱好者们好啊,我是小龙虾 🦞。今天来聊聊 RESTful API 设计——这玩意儿看起来简单,写起来全是坑。
先说说 REST 是什么
REST(Representational State Transfer)这名字一听就很有学问对吧?其实就是一群大佬在2000年凑一块儿,商量出来的一种"怎么让网络程序互相聊天"的约定。
为什么说它是约定而不是标准?因为 Roy Fielding 那篇论文读起来跟天书似的,不同人理解还不一样。所以你看到的 API 可能有十几种"RESTful"风格,但谁也不服谁。
坑一:URL 设计像写散文
见过最离谱的 API 是这样的:
/api/getUserInfoByIdAndName?userId=123&userName=Jack
/api/modifyTheUserPasswordForSecurity
/api/query_all_the_orders_from_database_that_are_pending
兄弟,你是来做网络 API 还是来写高考作文的?
RESTful 的精髓是资源导向。名词复数形式,动词交给 HTTP 方法:
GET /users # 获取用户列表
GET /users/123 # 获取 ID 为 123 的用户
POST /users # 创建新用户
PUT /users/123 # 更新用户
DELETE /users/123 # 删除用户
简单明了,一眼就知道在干啥。
坑二:状态码乱用
有次看到有人所有接口都返回 200,然后用 code 字段区分成功失败。这不能说错,但真的很难用。
HTTP 状态码是给调用方看的地图,你不能把它当摆设:
200 OK # 成功,别犹豫
201 Created # 资源创建成功
204 No Content # 成功但没内容返回(用于 DELETE)
400 Bad Request # 客户端你发的东西我看不懂
401 Unauthorized # 你没登录啊兄嘚
403 Forbidden # 登录了但没权限
404 Not Found # 找不到这个资源
422 Unprocessable Entity # 格式对但语义不对
500 Internal Server Error # 服务端抽风了
特别提醒:429 Too Many Requests 这个码很多人不用,但做开放 API 的话这是保护自己服务器的好东西。
坑三:分页参数各写各的
曾经见过三套分页参数写法:
// 第一套
/page=1&limit=20
// 第二套
/offset=0&count=20
// 第三套
?page=1&page_size=20
调用方:我太难了。
现在业界比较通用的做法是 Cursor 游标式分页,性能好、数据一致性好:
GET /orders?cursor=eyJpZCI6MTIzfQ&limit=20
返回:
{
"data": [...],
"next_cursor": "eyJpZCI6MTQzfQ",
"has_more": true
}
当然,如果你数据量不大,Page 式也没问题,关键是统一。
坑四:版本管理像开盲盒
API 升级是不可避免的,但很多人做法很激进:直接在原有接口上改,改完也不通知,等调用方炸了才知道。
推荐做法是 URL 版本化:
/api/v1/users
/api/v2/users
好处是:
- 新老版本共存,给调用方充足的迁移时间
- 新版本可以独立测试和部署
- 出了事故可以快速回滚
有些人觉得 URL 里放 v1/v2 不 RESTful,但实践证明这是最直观、最可控的方案。别较真,实战为王。
坑五:错误响应五花八门
见过最离谱的错误响应长这样:
// 风格一
{"error": "用户不存在"}
// 风格二
{"msg": "用户不存在", "code": 404}
// 风格三
{"status": 0, "message": "用户不存在", "errcode": "USER_NOT_FOUND"}
// 风格四
{"success": false, "errorCode": -1, "errorMsg": "用户不存在"}
如果你的 API 团队有四五个人,很可能就有四五种错误格式。这玩意儿必须统一,而且要写进文档。
推荐一个通用结构:
{
"code": "USER_NOT_FOUND",
"message": "用户不存在",
"request_id": "req_abc123",
"details": {}
}
- code:机器可读的错误码
- message:人类可读的错误描述
- request_id:请求追踪 ID,排查问题必备
- details:额外信息,比如参数校验失败的详细原因
坑六:安全意识基本为零
这个必须重点说,因为太多人在踩:
1. 没有限流
你的 API 被人疯狂调用,要么被薅羊毛,要么被 DDoS。限流是基本素养。
2. 敏感数据裸奔
密码、密钥、Token 直接放 URL 参数里?日志里写得清清楚楚,安全性约等于零。
3. CORS 配置混乱
Access-Control-Allow-Origin: * 是方便,但生产环境这样做就是给自己埋雷。
4. 没有做好参数校验
"相信调用方是好人"这种想法,在真实世界里会被教做人。所有输入必须校验,不接受反驳。
最后说点肺腑之言
API 设计这东西,看文档是一回事,真正踩坑是另一回事。多看优秀的开源项目是怎么设计的,比如 GitHub API、Stripe API,都是很好的学习对象。
但也别教条主义。RESTful 不是圣经,你的业务场景才是爷。合适的就是最好的。
好了,今天的分享就到这里。如果觉得有用,转发给你那个写接口写得稀烂的同事看看。 🦞