写API五年,我踩过的那些坑比代码行数还多

2026-09-17 4 0

干了五年后端,我最深的感悟就是:写API一时爽,调试API火葬场。这话虽然夸张,但懂的都懂。今天不整虚的,把我这些年踩过的坑、悟出的道理,实实在在抖落出来。都是血泪史,能帮一个是一个。

一、错误处理:别让你的API变成玄学

先说个真事。有个同事,调别人写的接口,400报错,愣是不知道哪里出了问题。日志呢?有。错误信息呢?写着「操作失败」。操作为什么失败?不知道。你说气不气?

我见过最离谱的错误响应是这样的:

{
  "code": -1,
  "message": "error"
}

看完我整个人都麻了。这error是什么意思?是我参数错了?数据库炸了?还是你程序员今天心情不好?

好的错误响应应该长这样:

{
  "code": 10001,
  "message": "用户不存在或密码错误",
  "detail": "根据user_id: 88888 查询未找到对应记录",
  "request_id": "req_abc123xyz"
}

你看,这就有诚意多了。code是给程序识别的,message是给人类看的,detail是给调试用的,request_id是用来查日志的。四件套配齐,调试效率翻倍。

还有,HTTP状态码要用对。别200回一个错误体,也不别404回个200配一个"success"字段。这是基本礼仪,不接受反驳。

二、参数校验:前端是你爹还是你是前端爹?

这个问题在团队协作里太常见了。前端说后端要校验,后端说前端会校验。然后两边都没校验,用户一顿操作,数据库里躺着一堆鬼数据。

我的原则是:信任但要验证。前端校验是体验优化,后端校验是安全兜底。你永远不知道用户会用curl还是Postman还是手写请求来调你的接口。

参数校验要做到:

  • 类型校验:字符串就是字符串,数字就是数字,别搞隐式转换那套
  • 长度校验:用户名最大20字符,你数据库varchar(20),就别让人家输入100个字符然后boom
  • 格式校验:邮箱就校验邮箱格式,手机号就校验手机号格式,别指望用户自觉
  • 业务规则校验:库存不足、余额不够、权限不足,这些校验一个都不能少

用成熟的校验库,别自己造轮子。我见过有人校验邮箱用正则写了几十行,然后漏了个边界情况。上spring-validation,它不香吗?

三、版本管理:v1写完不是终点,是噩梦的开始

很多新手以为API上线就完事了。不,这才是开始。等你需要加字段、改逻辑、删接口的时候,就知道版本管理有多重要了。

URL版本是最直观的方式:/api/v1/users/api/v2/users。好处是浏览器里直接能看出来,坏处是有时候版本太多维护起来麻烦。

我的建议:大版本走URL,小改动走响应头。breaking changes必须升版本,增量添加用deprecation标记慢慢过渡。别一上来就v3、v4,显得你很慌。

还有一个血泪教训:接口废弃要给足缓冲期。至少两个版本内还在维护,提前发deprecation警告,通知到具体的使用方。别突然一刀切,人家生产环境直接爆炸,你就等着接电话吧。

四、幂等性:这玩意儿你没搞懂就别上线

幂等性是什么?就是你同一个请求执行一次和执行一百次,结果是一样的。听起来简单,但坑巨多。

举个例子:用户下单接口,点击快了连续触发两次,扣了用户两次钱。你猜用户会不会炸?

解决方案:

  • 前端防抖:按钮点击后disable,这个能挡住一半的重复请求
  • 请求唯一标识:前端生成uuid,后端用redis或数据库记录,已处理的直接返回成功
  • 乐观锁/悲观锁:数据库层面的保护,记得用上

GET要天然幂等,POST一般不幂等,PUT和DELETE要看实现。这些概念不清不楚就别碰高并发场景,你把握不住的。

五、分页:没有分页的列表接口都是耍流氓

早期我写列表接口,select * from users一把梭。结果用户量大了,接口超时,然后被运维追着打。那场景,至今记忆犹新。

分页是刚需,不是可选项。两种主流方式:

offset模式:?page=1&page_size=20,简单直观,但深度分页性能差

cursor模式:?cursor=xxx&limit=20,性能好,但无法跳页

我的建议:数据量百万级以下用offset,超过百万用cursor。返回的时候把总数total带上,前端分页器需要这个。

还有个坑:count(*)有时候很慢。可以适当缓存,可以用条件索引优化,别傻傻每次都select count(*)。

六、文档:没文档的API跟没注释的代码一样欠揍

我知道写文档很烦,但请你想想:别人调你接口的时候,对着空白文档发呆,那个画面多让人绝望。

工具推荐:

  • Swagger/OpenAPI:代码即文档,注解生成,最省心
  • Apifox/Postman:团队协作神器,边调试边写文档
  • 自建doc站点:搭一套markdown文档系统,版本管理和搜索都方便

文档要写什么?

  • 每个接口的用途、请求方式、完整参数说明
  • 请求示例和响应示例,越详细越好
  • 错误码字典,每个code代表什么意思
  • 认证方式,怎么获取token
  • 调用频率限制,超了会怎样

文档写得好,下班走得早。这话我说的。

七、写在最后

写API这件事,说难不难,说简单也不简单。入门级选手能把功能跑通,进阶级选手能把接口写稳,高手能把API设计得像艺术品。

但不管哪个级别,有一点是共同的:多替调用方想想。你多花半小时写清楚的错误提示,别人可能少踩一个坑。你多花一天做的参数校验,可能避免一次线上事故。

代码是写给人看的,顺带机器执行。API是给别人用的,顺带机器调用。这个顺序搞反了,你的接口就废了。

行了,今天就唠到这儿。有什么想问的,评论区见。别跟我说你还在写{"code": -1, "message": "error"},我不想认识你。

相关文章

你的数据库查询正在偷偷杀死你的应用——而你还在写”更优雅”的代码
老板让我做实时通信,我差点把服务器polling到冒烟
不想折腾了?让小龙虾帮你一键部署AI工具,省心又省力!
写API这事儿:那些年我踩过的坑和良心建议
写API这事儿:那些年我踩过的坑和良心建议
你还在无脑上K8s?你的服务正在被它慢慢杀死

发布评论