webapi开发

 人参与 | 时间:2026-10-17 07:27:52

写WebAPI,第一件事不是写代码,是想清楚接口给谁用。给前端SPA调,和给第三方开发者调,设计完全两码事。我见过一个团队,内部用的接口返回结构里嵌了五层嵌套,前端每次取值都得写一长串 res.data.result.list[0].items。后来要开放给合作伙伴,对方看了文档直接说"你们先改改再来谈"。

RESTful不是圣经。很多人把GET、POST、PUT、DELETE当成铁律,结果遇到批量删除还得发一堆DELETE请求。实际项目中,POST /api/users/batch-delete 比循环调DELETE干净得多。HTTP方法只是约定,不是法律。关键是语义清晰,调用方看一眼URL和参数就知道会发生什么。

状态码要用对。我见过接口不管成功失败都返回200,然后在body里塞 { "code": 500, "msg": "error"}。这种做法让HTTP缓存、监控、网关全部失效。401就是401,404就是404,500就老老实实500。有一次排查线上问题,发现某个服务把所有异常都包成200返回,结果Nginx的access log里全是200,根本看不出错误率。后来改成正确的状态码,监控立刻就能报警了。

参数校验别偷懒。前端校验是给用户体验的,后端校验是保命的。有人觉得前端已经限制了输入长度,后端就不查了。结果被人直接curl调接口,塞了几MB的字符串进去,数据库字段直接截断报错。用框架自带的校验器,比如Java的Bean Validation、Python的Pydantic,几行注解的事。别自己写一堆if-else,又丑又容易漏。

版本管理要提前想。/api/v1/users 这种URL路径带版本号最直观。也有人在Header里放 Accept: application/vnd.myapp.v2+json,看起来优雅,但调试的时候用curl还得手动加Header,麻烦。路径版本号虽然不够"纯粹",但胜在简单直接。我倾向于URL带版本,等v2真的不兼容v1的时候,老接口还能继续跑着,给调用方留迁移时间。

错误信息要具体。"参数错误"这四个字等于没说。好的错误返回长这样:{ "error": "INVALID_EMAIL", "message": "邮箱格式不正确", "field": "user_email"}。调用方拿到之后能直接定位问题,不用翻文档猜。错误码用字符串比数字好,数字码过一阵子自己都忘了哪个是哪个。字符串码自解释,USER_NOT_FOUND 比 10023 强太多。

分页别用offset。数据量小的时候 ?page=1&size=20 没问题,数据一多,翻到后面几页查询越来越慢,因为数据库要扫描前面所有行。用游标分页,传个 last_id 或者时间戳,每次查 WHERE id > last_id LIMIT 20,速度稳定。前端可能觉得麻烦,但接口响应时间从2秒降到50毫秒的时候,他们就不抱怨了。

限流要做。哪怕内部接口也要做。曾经有个定时任务写错了,每秒往接口发几千个请求,直接把服务打挂。后来加了令牌桶限流,单IP每秒最多100次,超了返回429。简单有效。别等出事了再加,那时候已经在救火了。

文档用Swagger或者OpenAPI自动生成。手写文档一定会过期。代码改了文档没改,调用方按文档调不通,然后来问你,你再去翻代码,浪费双方时间。注解写清楚,启动时自动生成文档页面,代码即文档。省事。

最后说一句,接口设计没有绝对的对错。团队内部达成一致,调用方用着舒服,出问题能快速定位,就是好设计。别为了"优雅"把简单事情搞复杂。

顶: 8998踩: 4