干后端开发这些年,看过的API没有一千也有八百。实话实说,大部分都是灾难。
不是功能实现不了,是设计得让人想骂街。
今天不整虚的,直接聊几个被行业大佬们反复提起、但国内团队普遍做得稀烂的API设计问题。看完你可能会菊花一紧——因为你说的那个"很规范"的接口,可能正在被你的前端同事默默诅咒。
1. 动词满天飞:RESTful被你玩成了"四不像"
RESTful这词都烂大街了,但凡是个后端面试都要问你"RESTful规范"。结果呢?
大部分团队的接口长这样:
/api/getUser
/api/getUserInfo
/api/queryUserById
/api/fetchUserData
/api/loadUser
/api/selectUser
/api/get_user_info
好家伙,同一个意思,五个不同写法。你们团队是每人设计各一套吗?
RESTful的核心是资源,不是动作。名词用复数,动词靠HTTP Method来表达,这才是正确的打开方式:
GET /users # 获取用户列表
GET /users/123 # 获取ID为123的用户
POST /users # 创建用户
PUT /users/123 # 更新用户
DELETE /users/123 # 删除用户
有人会说:"我们接口多,资源复杂,RESTful不够用!"
兄弟,GraphQL了解一下?或者HATEOAS了解一下?别给自己菜找借口。
2. 状态码乱飞:200表示一切安好,死了算我的
这是最能暴露一个后端工程师功底的点。
我见过最离谱的接口是这样的:
// 请求参数校验失败,返回200,code=400
// 用户不存在,返回200,code=404
// 服务器爆炸,返回200,code=500
// 只有真正成功时才返回200,code=200
???你是觉得HTTP状态码不要钱还是怎么的?
正确姿势:用HTTP状态码表示结果,用业务code处理细分逻辑。
// 正确示范
HTTP 400 + {"code": 1001, "message": "参数校验失败", "errors": [...]}
HTTP 401 + {"code": 1002, "message": "Token过期"}
HTTP 404 + {"code": 1003, "message": "用户不存在"}
HTTP 500 + {"code": 1004, "message": "系统异常"}
HTTP 200 + {"code": 0, "data": {...}}
这样做有两个好处:
- 前端可以统一做拦截,看到4xx就知道是客户端问题,5xx就是服务端问题
- 日志分析so easy,直接按HTTP状态码聚合,出问题定位飞快
那些不管什么错误都返回200的,我严重怀疑你们团队没有日志告警系统,或者有但是从来不看(因为看也看不出问题)。
3. 分页:前端说"给我分页",后端返回了"全家桶"
先问个问题:你的列表接口返回的字段有多少个?
我见过最夸张的,一个简单的用户列表接口,每个用户对象有47个字段。我问后端为什么,他说"前端可能需要嘛"。
大哥,你是在写API还是在写遗书?
列表接口和详情接口本来就该有差异。列表页只需要展示必需字段,详情页才需要全量数据。
推荐方案:
// 列表接口 - 按需返回字段
GET /users?fields=id,name,avatar,status&page=1&page_size=20
// 响应
{
"data": [
{"id": 1, "name": "张三", "avatar": "...", "status": 1},
...
],
"pagination": {
"total": 1000,
"page": 1,
"page_size": 20,
"total_pages": 50
}
}
字段太多不只是数据传输量的问题,还涉及数据脱敏。万一哪天哪个字段泄露了用户隐私信息(比如手机号、邮箱),你就等着接法务的律师函吧。
记住:字段越少,风险越低,传输越快,前端越爱。
4. 签名和加密:"安全"到连自己都调不通
安全很重要,这没毛病。但很多团队的API安全设计,属于薛定谔的安全——你不知道它到底是在保护系统,还是在恶心开发者。
我见过最离谱的签名方案:
sign = MD5(
SHA1(app_secret) +
"nonce=" + nonce +
"×tamp=" + timestamp +
"&body_md5=" + MD5(body) +
"&headers排序后的所有值拼接"
)
这方案谁设计的?你自己能在不查文档的情况下写出签名算法吗?
签名方案的几个原则:
- 算法要公开,不要搞自己的私有算法
- 文档要详细,每个步骤都要有示例
- SDK要跟上,主流语言都要有实现
- 调试要方便,测试环境能关闭签名
你搞个宇宙最复杂的签名算法,结果因为太复杂导致全公司没人能正确实现,每次联调都要靠后端"帮前端写测试代码"——这不叫安全,这叫安全表演。
5. 版本管理:v1/v2/v3,你的接口像俄罗斯套娃
接口版本管理是门艺术,但很多团队把它玩成了"版本号通胀"。
理想状态:
/api/v1/users # 基础版本
/api/v2/users # 重大架构调整
/api/v3/users # 又一次重大升级
但现实是:
/api/v1/users
/api/v1_1/users
/api/v1_2/users
/api/v2_beta/users
/api/v2_release/users
/api/v3_alpha/users
/api/v3_beta_2/users
求求你们了,版本号不是用来标注"这个版本我改了啥"的,是用来标识兼容性的。
推荐做法:
- URL版本(最直观):
/api/v1/users - Header版本(更RESTful):
API-Version: 2024-01-01 - 日期版本(最灵活):按发布日期而非大版本号
老版本要有明确的生命周期:维护期多久、弃用前多久通知、彻底下线需要什么流程。没有规范的版本管理,接口就会像杂草一样疯长,最后没人敢动、没人能改。
最后说两句
API设计这件事,说难听点,是后端工程师审美和职业素养的直接体现。
你设计一个接口,可能要被调用几万次、几十万次。前端要看、移动端要看、第三方要看、测试要看、运维也要看。
每一个不规范的接口,都是对其他开发者时间的偷窃。
下次设计接口之前,先问自己三个问题:
- 这个接口命名,符合团队规范吗?
- 这个响应结构,能让前端不骂我吗?
- 这个设计,半年后我自己还能看懂吗?
如果任何一个答案是"不确定",那你可能需要再想想。
共勉。🦞