进销存 Web 版 REST API 设计
接口是前后端协作的契约,也是将来开放给第三方系统对接的门面。进销存业务单据多、状态流转复杂、对账要求严,接口设计一旦草率,后期对接和排错成本极高。本文梳理我们 Web 版进销存 API 的设计约定,涵盖 URL 规范、响应格式、鉴权和幂等四个核心问题。
一、URL 设计:资源名词 + 业务动作显式化
REST 的基本原则是用名词表示资源,用 HTTP 方法表示操作。进销存的核心资源是商品(goods)、单据(orders)、库存(stock)。基础 CRUD 很直接:
GET /api/v1/goods # 商品列表(分页)
GET /api/v1/goods/123 # 商品详情
POST /api/v1/goods # 新建商品
PUT /api/v1/goods/123 # 更新商品
DELETE /api/v1/goods/123 # 停用商品(软删除)
但进销存有大量业务动作:审核、反审核、出库确认、盘点差异处理。这类动作如果硬塞进 PUT 语义不清,我们的约定是显式子资源:
POST /api/v1/orders/456/review # 审核
POST /api/v1/orders/456/unreview # 反审核
POST /api/v1/stock/count # 盘点录入
POST /api/v1/stock/adjust # 库存调整
版本号放在路径第一段(/api/v1/),不破坏式升级时升版本、旧版保留一个过渡期,给对接方留迁移时间。
二、统一响应格式
所有接口返回统一的信封结构,前端处理逻辑可以收敛到一个请求封装里:
{
"code": 0, // 0 成功,非 0 业务错误码
"message": "ok",
"data": { ... },
"traceId": "a1b2c3" // 排查问题时全链路定位
}
列表接口统一分页参数 page 和 pageSize(上限 200),返回 data.list + data.total。错误码分层:1xxxx 参数错误、2xxxx 业务规则拒绝(如库存不足)、3xxxx 权限问题、5xxxx 系统异常。业务错误必须把"为什么拒绝"说清楚——"库存不足,当前可用 15,需出库 20"远比"操作失败"有用。
三、鉴权:Token + 签名
登录后签发 Access Token(有效期 2 小时)+ Refresh Token(7 天),前端 401 时静默刷新重试原请求,用户无感。接口签名按这个顺序:请求头带 Authorization: Bearer <token>,敏感写操作再加时间戳 + 请求体摘要签名,防止抓包重放。
权限粒度到按钮级:后端每个接口校验权限点(如 order:create),不能只靠前端隐藏按钮。数据权限同样在后端落实——业务员只能看到自己客户的单据,这条校验写在查询构造层,所有列表接口自动生效。
四、幂等:写接口的底线
网络重试、用户连点、PWA 离线同步,都会让同一个写请求到达多次。写接口幂等是进销存 API 的底线要求,做法:
- 新建单据:客户端生成 UUID 作为
Idempotency-Key请求头,服务端按此键唯一约束,重复提交直接返回首次结果。 - 审核动作:服务端校验当前状态,已审核的单据重复审核返回幂等成功而非报错。
- 金额变动:所有收付款、成本变动用流水表记账,天然可重算可对账,不直接改余额字段。
幂等键与离线队列的配合详见 PWA 离线应用实践——离线开单同步全靠它防重。
五、文档与调试
接口文档用 OpenAPI 3 描述,注解方式从代码生成(Spring 用 springdoc,Node 用 zod-to-openapi),保证文档和实现永不脱节。生成的文档站部署在内网,前端和后端对着同一份契约开发,联调成本能降一半。
结语
好的 API 设计标准只有一句话:让调用者一次猜对、出错能懂、重试安全。URL 显式化、响应信封统一、写操作幂等,这三件事做好了,进销存的接口就不会成为系统演进的负担。