干过后端开发的同学,大概都有过这种体验:对接一个第三方API,文档写得跟谜语似的,返回状态码全靠猜,错误信息写着"操作失败请联系管理员"——管理员是谁啊?人家在度假呢。
一个烂API的杀伤力,远超你想象。它不只是调用者的问题,是整个团队的问题——每次对接都是一次信任的消耗。今天来聊聊那些让开发者血压飙升的API设计坏习惯,顺便给点真正有用的建议。
坑一:命名各凭本事,统一?不存在的
我见过最离谱的API是这样子的:
GET /api/getUserInfo # 用get
GET /api/query_order # 用query
POST /api/create_new_item # 用create
PUT /api/modify_user # 用modify
DELETE /api/removeOrder # 用remove
兄弟,你是认真的吗?同样是资源操作,动词用得跟买彩票似的。调用方每次都得把文档翻个底朝天,就为了猜你今天心情不好用了哪个词。
正确做法:RESTful的核心就是用HTTP方法表达动作,资源命名用名词复数。GET /users、POST /users、PUT /users/:id、DELETE /users/:id,清晰到不需要文档。做不到这点,至少给自己定一套命名规范,别让团队成员各凭感觉。
坑二:状态码全靠感觉,200代表一切
这是另一个重灾区。多少人写API,所有接口都返回200,然后内部自己搞个code字段:
{
"code": 500,
"message": "服务器爆炸了",
"data": null
}
喂,200的意思是"搞定了",不是"出错了但我假装没事"。HTTP状态码是有标准的,用403表示禁止访问,用404表示资源不存在,用500表示服务器抽风,这些不需要发明轮子。
正确做法:老老实实用标准状态码。2xx表示成功,4xx表示客户端问题(你该修代码),5xx表示服务器问题(我们该修代码)。如果业务逻辑复杂,需要自定义错误码,在body里加code字段就行,但HTTP状态码本身别乱来。
坑三:分页设计反人类
有些API的分页参数,看得人怀疑人生:
GET /orders?page=1&size=20&offset=10&limit=50
你到底想让我看哪一页?page、size、offset、limit四个参数,其中三个是多余的。这种设计要么是写API的人自己都忘了用过哪些参数,要么就是每次写的时候随手一加,从来没整体考虑过。
正确做法:分页就两种常用模式:
- 页码模式:page + page_size,适合列表类业务场景
- 游标模式:cursor + limit,适合大数据量或实时性强的场景
选一种,全站统一。别让调用方去猜你今天想用哪种参数名。
坑四:版本管理像过家家
URL里写版本号是常见做法,但很多项目写着写着就乱了:
/api/v1/users
/api/v2/users
/api/beta/users
/api/latest/users
/api/3rd/users # 什么?
每个版本还有不同的返回结构,文档也没有更新,调用方只能靠经验猜。API版本管理的本质是:老客户不受影响,新功能有新接口可享。做不到这点,版本号就是装饰品。
正确做法:版本号进URL(如 /v1/)或者进Header(如 Accept: application/vnd.api+json; version=1),但必须有明确的版本策略文档,说明每个版本的生命周期、何时废弃、迁移路径。没有文档的版本管理就是耍流氓。
坑五:错误信息等于没说
这个问题能排进"最让调用者崩溃"前三名。错误信息写得像诗——优美但无用:
{
"code": -1,
"message": "操作异常",
"data": null
}
操作异常是什么意思?是参数错了?权限不够?还是服务器在做梦?这时候调用方的开发只能开始他的debug之旅:加日志、重现请求、翻代码、查数据库。两个小时的排查,可能就因为你多打了几个字。
正确做法:错误信息至少包含三个要素:错误码(方便排查)、人类可读的错误描述(方便理解)、以及请求ID(方便定位)。最好还能给出修复建议——比如"密码不能少于8位,请检查您的输入",比"参数校验失败"有用一万倍。
Bonus:文档和API不一致,这算欺骗吗?
这大概是排名第一的坑王:文档写的是一套,实际返回的是另一套。字段名对不上、类型对不上、甚至连有没有这个字段都不确定。
我个人的习惯是:文档即代码。Swagger/OpenAPI文档应该从代码注释里自动生成,而不是手写。手写的文档,三天后就开始和代码分道扬镳。
写到最后
API设计这东西,入门容易,写好很难。它不需要什么高深的技术,但需要一点基本的工程素养和对调用者的尊重。
记住:你的API是给别人用的工具,不是展示自己技术深度的舞台。能把复杂的事情写得简单、清晰、易用,这才叫本事。
下次写API之前,想象一下调用你接口的那个人:他可能正在深夜debug,可能对你们的系统一无所知,可能只是想要一个能用的接口。让他的路走得更顺一点,也是给自己省事。
毕竟,你们以后还要一起排查问题呢。