后端设计 API 的时候的 7 条注意事项
时间:2025-12-29 00:22 作者:独元殇 分类: 开发相关
这种属于后端的功能,需要经验才能写的好。下面是一些防止【亡羊补牢】的提醒点,也是自己的经验。看着很枯燥简单,但你设计时还不一定能一下子全想到哈。建议大家可以用于对照,在设计 API 的时候挨个补全,我觉得我这个还算全面:
第1点,API 地址里打上版本号
这个大家可能很容易忽略。尤其是新手
这句话是这个意思:
老接口:/api/v1/users (给旧版 客户端 用)。
新特性:/api/v2/users (给新版 客户端 用)。
建议生产环境下的 API 都要有这个版本号。
版本控制是很重要的。随着开发的复杂度增加,不同时代的 API 会同时都有在用,等绕成一大片迷宫,发现迷路的时候已经晚了!
第2点,不要一口气把数据全给前端
这个老生常谈,但是我们还是都喜欢这样。
其实 REST API 已经可以去请求自己的数据了。
// 带上参数:/api/users/123?fields=name,email
const fields = req.query.fields?.split(',') || ...
// 只要 name 和 email
const user = await db.users.findById(req.params.id, { select: fields });
res.json(user);
先不说浪费流量、安全问题。
起码原来那种 REST API 一把梭(也就是全返回)的做法,往往会容易把数据包搞的很大,不明确,浏览器和服务器,缓存都很难去做。
养成好习惯!
第3点,好好写报错的内容,不要太模糊
报错这个东西,很重要。
我们平时可能用不到,开发的时候有很多可能也不太能用到。
但是!
生产环境下,如果你就看到下面这种报错信息,你心里什么感受?
500 Internal Server Error: { "error": "Something went wrong" }
杀人的心都有了!
我们要养成好习惯,起码把字段错误给标出来。
就像上面,到底是哪里错了?服务器宕机了?密码错了?网断了?
错误码也要对照,写的规范一点,不能一个 500 一把梭哈!
409 是冲突,400 坏请求,404 找不到,500 服务器宕机.....
第4点,默认一定要有限流
所有接口,所有接口,都默认会有个坏人,用脚本来疯狂搞。
所以,所有一定要有个限流!
如果越界了,就返回 429 错误!
比如 15 分钟内,最多请求 100 次!
如果没有这些,迟早有一天,会付出金钱代价!
第5点,避免无限分页
无限分页只是一个比喻, 就跟刷小红书 抖音一样,一下子刷个不停了。
也就是你在请求数据的时候,就一口气要很多很多。
现在我们要使用 Cursor-based ,也就是页面(游标),基于游标去搞页面,同时这个也是个【负载可预测】。
在页面少的时候,可能你觉得没什么,一旦数据多了,这个就是个安全隐患。
强制限流:
// 最多只给 100 条
const limit = Math.min(parseInt(req.query.limit) || 20, 100);
这也是一个好习惯。
起码,能做到,你数据库有 1 亿条数据 ,你的请求速度一样很快。不能亡羊补牢。
新手很容易忽略这个。
第6点,要说实话,用对状态码!
很常见的错误。
这里指的 HTTP 状态码,就是下面这个表:
当然,更详细的,要查一下权威的 MDN 数据:
HTTP 响应状态码 - HTTPdeveloper.mozilla.org/zh-CN/docs/Web/HTTP/Reference/Status
再不行,就问问 AI 。
我在工作中不止一次,收到后端递给我的 200 OK ,但没给我办成事.....
要用对!
尤其是新人后端(貌似很多很多公司,都是这样写的...),把后端当玩具了,大脑一股清流地全部 200 OK ,真正的状态写在消息里。比如 { "code": -1, "msg": "失败" } 。
你的运维肯定不喜欢一大堆 OK ,更喜欢 401-Unauthorized、403-Forbidden、408-Request-Time-out、404-not-found。
当然也不是说这样程序跑不起来了,而是后续你要使用一些监控工具的话,就监控不了了。
网关也监控不到。
第7点,缓存(主要指头部缓存)
简单说,不要让所有请求,都进数据库去操作。
小项目还行,大项目不能。
如果有个坏人,它一秒查一次商品库存,像类似的 API 多了,数据库会炸。
抵御 DDOS 的能力都变的差很多。
但,请求也不能全部都不进数据库查吧?!
2025 2026 的今天,有个更好的解决方案
就是头缓存。第一次请求的时候,给的接口里面加上头部缓存,这样后续的请求,就被 CDN 拦截了,就不进数据库了,类似于下面这个:
res.set({
'Cache-Control': 'public, max-age=300', // 5 分钟缓存
'ETag': '...' // 数据指纹
});
这样,等于告诉外界,这个数据 5 分钟才查一次。5 分钟内都不会变。算是这里压轴的小技巧吧。