前后端分离架构下,API 就是前后端协作的契约。契约不规范,前端要写一堆兼容代码、后端要反复返工,联调阶段更是互相甩锅。本篇总结尧图建站团队的 API 设计规范,从 URL 到响应到鉴权,建立一套前后端都能愉快协作的接口约定。
一、RESTful 风格与 URL 设计
RESTful 的核心是"资源 + HTTP 动词"。URL 表示资源(名词),HTTP 方法表示操作(动词),两者组合表达意图。规范的设计能让接口自解释,看 URL 就知道在操作什么。
GET /api/v1/articles # 文章列表
GET /api/v1/articles/123 # 文章详情
POST /api/v1/articles # 新建文章
PUT /api/v1/articles/123 # 更新文章(整体)
PATCH /api/v1/articles/123 # 更新文章(局部)
DELETE /api/v1/articles/123 # 删除文章
URL 设计有几个要点:用复数名词(articles 而非 article);资源层级用斜杠表达(/articles/123/comments);查询参数用于过滤分页(?page=1&size=20&status=published);动作类操作无法用动词表达的,用子资源(POST /articles/123/publish)。切忌把动词写进 URL,如 /getArticleList、/deleteUserById 都是反模式。
二、统一响应结构与错误处理
接口返回必须用统一结构包裹,前端只需写一套解析逻辑。尧图的规范是用 code 表示业务状态码、message 表示提示、data 承载数据。HTTP 状态码仍要正确设置(200 成功、400 参数错、401 未授权、404 不存在、500 服务错),业务码则用于更细的错误区分。
// 成功响应
{
"code": 0,
"message": "success",
"data": {
"list": [...],
"total": 128,
"page": 1,
"size": 20
}
}
// 错误响应
{
"code": 40001,
"message": "文章标题不能为空",
"data": null
}
code: 0表示成功,非 0 表示业务错误,便于前端统一判断。- 分页数据固定用
list/total/page/size四字段,前端组件可通用。 - 错误信息要面向用户可读,不要直接抛技术堆栈。
- 时间字段统一用 ISO 8601 或时间戳,避免时区歧义。
三、版本管理与鉴权安全
接口难免要迭代,硬改老接口会打断线上前端。规范的做法是 URL 里带版本号(/api/v1/),大版本升级时开 v2 并保留 v1 一段时间,给前端迁移留窗口。小改动(加字段、加可选参数)在原版本内做,保持向下兼容。
// 鉴权:登录后颁发 token,后续请求头携带
// 请求头格式
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
// 后端中间件校验流程
function authMiddleware(req, res, next) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) return res.fail(401, '未登录');
try {
const payload = jwt.verify(token, SECRET);
req.userId = payload.uid; // 注入用户信息
next();
} catch (e) {
return res.fail(401, '登录已过期');
}
}
鉴权方面,企业后台推荐 JWT(无状态、易扩展)。token 里只放用户 ID 和过期时间,敏感信息别塞进去(JWT payload 是 base64 可解码)。token 设置合理有效期(如 2 小时),配合 refresh token 续期,兼顾安全与体验。所有写操作必须做权限校验(参考上篇 RBAC),不能只靠前端隐藏按钮——接口才是最后一道防线。
把这些规范固化成团队约定,再配合接口文档工具(如 Apifox、Swagger),前后端协作效率会显著提升。好接口的标准就是:前端不用问、后端不用改,联调一次过。