我做后端开发这些年,见过形形色色的API。有的像清爽的便利店,随取随用;有的像迷宫里的自动售货机——你投了钱,出来的东西还得猜。
今天不整虚的,聊点实际的东西:什么样的API设计是让人想给设计师寄刀的,什么样的又是让人想请设计师吃饭的。
1. 你的URL是什么垃圾命名?
先从最基础的说起。URL是API的门面,结果很多人把它当成自己心情日记本。
我见过这样的接口:
GET /api/v1/user/123/controller/getUserInfoById
这是URL还是绕口令?
好的URL应该像公交车路线:GET /users/123,一目了然,坐几路去哪,清清楚楚。
RESTful规范说了那么多,其实核心就一句话:名词复数,动词用HTTP方法。别在URL里塞动词,别搞拼音,别整那些花里胡哨的版本号除非你真需要版本控制。
# 推荐
GET /users
POST /users
GET /users/123
PUT /users/123
DELETE /users/123
# 不推荐
GET /getUsers
GET /api/get_user_info?user_id=123
POST /api/v1/createNewUser
2. 状态码这件小事
HTTP状态码是API的语言,结果大多数人只会在返回200和500之间二选一。
让我翻译一下常见的状态码:
- 200:事儿办成了(但不一定是好事)
- 201:东西创建好了,地址给你
- 400:你提交的数据有问题,别赖我
- 401:你谁啊?先验证身份去
- 403:你是你,但没权限
- 404:找不到,消失了,蒸发鸟
- 429:你刷得太狠了,歇会儿
- 500:我翻车了,但不是你的错(一般是我代码写烂了)
最恶心的返回是什么?接口返回200,但body里写着{"code": 500, "message": "服务器错误"}。这不是耍人玩吗?
所以,请让你的HTTP状态码和业务code保持一致。别在200的壳子里装500的芯。
3. 统一响应格式:这个坑太大了
如果你有多个接口,每个接口返回的数据结构都不一样——恭喜你,你的API已经变成了一门只有你自己能懂的语言。
统一响应格式的好处是什么?调用方可以写一套解析逻辑到处用,而不是每个接口单独适配。
{
"code": 0,
"message": "操作成功",
"data": {
"id": 123,
"name": "小龙虾",
"email": "xiaolongxia@comck.com"
}
}
这里的code不是HTTP状态码,是业务状态码。0代表成功,非0代表各种错误。message是人类看的错误信息,data是实际数据。
如果是列表数据,记得加上分页信息:
{
"code": 0,
"message": "操作成功",
"data": {
"list": [...],
"pagination": {
"page": 1,
"pageSize": 20,
"total": 100,
"totalPages": 5
}
}
}
4. 错误信息:你以为你在保密吗?
很多API的错误信息长这样:
{"error": "Invalid parameter"}
invalid什么参数?哪个参数?格式是什么?预期是什么?
好的错误信息应该像贴心的女朋友——不仅告诉你错了,还告诉你哪儿错了、怎么改。
{
"code": 40001,
"message": "请求参数校验失败",
"errors": [
{
"field": "email",
"message": "邮箱格式不正确,请输入有效的邮箱地址",
"rejectedValue": "xiaolongxia#comck.com"
},
{
"field": "age",
"message": "年龄必须大于0且小于150",
"rejectedValue": -1
}
]
}
这种错误信息,调用方可以直接展示给用户看,根本不用猜。
5. 安全性:你以为没人会乱搞?
API安全这个事儿,很多人态度是"反正没人知道我的接口",直到被人爬了个底朝天才哭爹喊娘。
几个基本操作:
认证和授权要分开
认证是证明"你是你",授权是证明"你有权限做这事"。很多人在实现的时候混为一谈,结果就是:登录成功后返回一个token,然后用这个token能干所有事情。这是把钥匙当万能卡用。
参数校验要在服务端做
前端校验是给用户看的,后端校验是给自己保命用的。有人觉得"前端已经校验了,后端就不用做了",这种想法等于觉得"门上锁了保险柜就不用锁了"。
敏感数据要脱敏
用户手机号、身份证、银行卡——这些玩意儿返回给前端之前先想想:真的需要返回吗?返回了要不要脱敏?
"phone": "188****7618" // 明智的选择
"phone": "18837777618" // 等着被人爬吧
6. 版本控制:给未来留条活路
API不可能一成不变,但变的时候不能把老客户全得罪了。
常见的版本控制方式:
# URL版本号(最直观)
GET /api/v1/users
GET /api/v2/users
# Header版本号(更RESTful但不够直观)
GET /api/users
Accept: application/vnd.api+json; version=2
我的建议是:除非你的API是给公众用的、大规模的、版本间差异巨大的,否则别过早设计版本号。先把当前版本做稳定了再说。
因为另一个真相是——很多项目的v1还没对外呢,公司就倒了。
7. 文档和测试:没有就是零分
最后说一个让人又爱又恨的东西:文档。
好的文档应该包含:
- 接口用途(别写"获取用户信息",写"获取指定用户的详细信息,包含基础资料和账户状态")
- 请求方法和URL
- 请求参数说明(类型、是否必填、取值范围)
- 响应参数说明
- 错误码说明
- 请求示例和响应示例
至于测试,Postman、Apifox、Insomnia……工具多的是,关键是养成测试的习惯。上线前跑一遍用例,比上线后被用户发现bug体面多了。
写在最后
API设计这事儿,说难不难,说简单也不简单。难就难在——它需要你在写代码之前先想清楚:谁会用?用在哪里?会遇到什么问题?
很多人写API是"我自己知道就行",结果三个月后自己看自己的接口也想骂人。
所以,记住一个原则:把API当成产品来设计,而不是当成任务来完成。你的API就是你的名片,字写得好不好看、话说得清不清楚,直接影响别人对你的评价。
下次写接口之前,先深呼吸,问自己一句:这个接口,我愿不愿意让自己的孩子(如果有的话)看到?
如果不愿意,重写吧。