9.5 KiB
9.5 KiB
NiuCloud 前后端一致性规范(NestJS × Java)
本文档明确 NestJS 应用与 Java 应用除统一响应格式外必须保持一致的关键约定,说明一致性的必要性、具体规范、验收标准与迁移指南,确保多语言后端与前端协同稳定、可维护、可观测。
1. 背景与必要性
- 降低前端适配成本:统一字段名、响应包裹和错误语义,避免双端分支逻辑。
- 提升可维护性:统一拦截器、异常处理与权限模型,减少跨语言心智切换和重复实现。
- 保证观测与排障效率:统一请求ID、租户传递、日志字段与错误码,提升链路追踪与故障定位速度。
- 保障合规与安全:统一认证、授权与租户隔离策略,避免安全边界不一致导致的绕过或误判。
2. 必须一致的清单(Checklist)
- 统一响应包裹结构:
code/msg/data(成功code=1,失败code=0)。 - 错误码与消息规范:统一错误枚举、消息来源与 i18n key 策略。
- 认证与授权模型:统一 Bearer Token 传递、角色/权限语义与公共路由标识。
- 租户解析与传递:统一租户头部名称与覆盖规则,后端取值一致。
- 分页入参与返回值:统一
page/limit入参与PageResult字段命名。 - 请求 ID 传递:统一
X-Request-Id生成、透传与日志打印位置。 - 路由前缀与版本策略:统一全局前缀、版本化与资源命名规范。
- 国际化与消息源:统一 i18n key 命名空间、默认语言与降级策略。
- Swagger 契约:统一响应包裹、错误结构与示例;字段命名与大小写约定一致。
- 日志与审计字段:统一日志级别、必填上下文字段与审计事件命名。
- 数据与时间格式:统一时间格式、时区、布尔/数字序列化与空值约定。
3. 统一响应与错误规范
- 统一响应:
{ code: number, msg: string, data: any }- 成功:
code=1,msg使用成功消息(可 i18n),data为业务数据。 - 失败:
code=0,msg来自错误枚举或异常转换,data可为空或附带上下文。
- 成功:
- 异常对齐:所有异常统一转换为上述响应,不直接裸露 HTTP 4xx/5xx(除少数基础设施路由)。
- 错误枚举:与 Java 的
HttpEnum/业务枚举保持一致;Node 端通过统一异常过滤器/拦截器映射。 - i18n:后端返回
msg优先 i18n key -> 文本,前端不再做二次翻译(避免双端分歧)。
4. 认证与授权(Auth & RBAC)
- 头部:
Authorization: Bearer <JWT>。 - 公共路由标识:Java 端拦截器白名单、Node 端
@Public()装饰器,含义一致且生效路径一致。 - 权限模型:
role与permissions(如secure.read)语义一致;路由守卫校验行为一致(读/写/管理粒度)。 - 失败语义:缺失/失效 Token、权限不足与租户不匹配统一错误码与消息(建议对齐 Java 枚举)。
5. 租户(Tenant)与请求头
- 头部名称:统一为
site-id(Node 端已移除x-tenant-id兼容)。 - 覆盖策略:若同时存在 Token 与请求头,优先使用 Token 中的租户。
- 优先级:
JWT.tenantId/siteId > header.site-id > fallback,避免前端覆盖 Token 租户。
6. 分页约定
- 入参:
page(默认1)、limit(默认10)。 - 返回:
PageResult = { currentPage, perPage, total, data }。 - 语义:
page从 1 开始;limit上限约束与校验一致;total为总记录数。
7. 请求 ID 与追踪
- 头部:
X-Request-Id,前端可传;后端若未传则生成并返回。 - 传播:同一请求在日志、错误响应与审计中均打印
requestId,便于跨端定位。
8. 路由与版本规范
- 用户端全局前缀:
api(示例:/api/secure/ping)。 - 管理端命名空间:
adminapi作为控制器路由段(示例:/adminapi/sys/get/website)。 - 版本:如需版本化,统一
v1路由前缀或 Header 版本策略,避免多种混用。 - 命名:资源名用复数;动词通过 HTTP 方法表达(
GET /users、POST /users)。
9. 国际化(i18n)
- 命名空间:
auth.*、tenant.*、error.*等统一;Key 与 Java 端保持同名。 - 默认语言:统一默认语言与回退策略;未命中 Key 时返回可理解的中文消息。
10. Swagger 与契约
- 统一响应包裹示例与错误结构;所有接口描述使用一致术语与字段命名。
- DTO 字段大小写与枚举值命名一致;分页入参与返回值在文档中统一标注。
11. 日志与审计
- 日志级别:统一 INFO/DEBUG/WARN/ERROR 语义;敏感字段脱敏一致。
- 审计:关键业务操作统一事件名与字段(如
actorId、tenantId、action、resourceId)。
12. 数据与时间格式
- 时间格式:统一
yyyy-MM-dd HH:mm:ss;时区统一为UTC+8(或明确全局约定)。 - 序列化:布尔与数字类型一致;空值策略一致(避免
null/undefined差异导致前端异常)。
13. 验收标准(示例)
- 公共路由:
curl -s http://localhost:3000/api/secure/public返回code=1。 - 受保护路由:携带有效 JWT(含
permissions: ["secure.read"])访问返回code=1。 - 租户透传:同一请求返回体/日志含
tenantId与requestId;头部与 Token 优先级一致。 - 分页:
GET /api/resource?page=1&limit=10返回统一PageResult字段。
14. 迁移指南
- 头部统一:前端与后端统一采用
site-id;移除x-tenant-id,避免双头不一致。 - 异常对齐:建立 Node 错误枚举与 Java 枚举的映射表;统一异常过滤器输出。
- i18n 整理:梳理公共 Key 清单,统一命名空间与默认消息。
- 分页对齐:检查 Node 控制器/服务分页返回结构,统一为
PageResult。 - 文档对齐:更新 Swagger 与前端类型定义,消除字段差异。
15. 维护与变更管理
- 任何变更必须同步更新:后端契约、Swagger、前端类型与此文档。
- 采用版本标签(如
consistency:v1)标注对齐里程碑,便于回溯。
附注:
- 目前 Node 端已在端到端验证下运行
/api/secure/public与受保护路由,响应与租户解析按上述约定工作。 - 管理端路由统一以
adminapi为命名空间;不使用全局前缀覆盖(避免/api/adminapi)。
16. 一致性任务清单(实施计划)
- 建立 Node 错误枚举与 Java 枚举映射(含 i18n key 与 msg)。
- 统一异常过滤器输出为
Result包裹,并携带requestId。 - 分页 DTO 与返回结构统一为
PageResult(含 Swagger 示例)。 - 请求 ID 中间件:生成/透传,日志与响应头一致。
- Swagger 响应与错误示例统一(分页、错误码、字段命名)。
- 日志字段与审计事件标准化(
requestId、tenantId、userId、ip、method、path、duration)。 - 时间与序列化规则统一(时区、ISO/显示格式、空值策略)。
- RBAC 权限命名与粒度对齐(读/写/管理),路由守卫策略一致。
- 路由前缀与版本策略对齐(
api、v1),资源命名复数。
每项验收要点(示例)
- 租户头:Token 与请求头同时存在时以 Token 租户为准,返回体与日志一致。
- 错误枚举:相同错误在两端
code/msg一致;Swagger 错误示例一致。 - 异常过滤器:所有异常统一包裹输出,含
requestId。 - 分页:
GET /api/resource?page=1&limit=10返回PageResult,字段与 Java 对齐。 - 请求 ID:若前端未传则后端生成,并在响应头与日志透传。
17. 兼容期与回退策略
- 若出现兼容问题,优先基于文档规则回退至仅
site-id,并在 Swagger 标注变更说明。
18. 前端对齐要点
- 拦截器统一设置
Authorization: Bearer与租户头(统一site-id)。 - 若存在
X-Request-Id,透传;否则由后端生成并返回后存档。 - 分页入参统一
page/limit;对齐返回PageResult类型定义。
19. 安全与运维一致性
- CORS:允许源、方法与头部策略一致,含
Authorization、site-id、X-Request-Id。 - 速率限制与登录防刷:策略一致,错误语义与返回结构一致。
- 健康检查:用户端统一
/api/health;管理端统一/adminapi/health。
20. 变更提交流程
- PR 必须附带文档更新、Swagger 更新与前端类型更新。
- 使用标签
consistency:v1标注合并项;在 CHANGELOG 记录对齐影响范围。
别名与模块边界(一致性约束)
-
映射规范:
@wwjBoot:仅用于顶层平台装配与入口(BootModule、preset)。@wwjCommon:统一基础设施入口(http、response、metrics、cache、queue、auth、tenant、lang)。@wwjVendor:第三方驱动适配层,按接口/Token 注入,默认“可选/存根”。@wwjAi:AI 能力模块,允许依赖@wwjCommon,不得依赖@wwjBoot。
-
强制规则:
- 禁止使用
@wwjBoot/infra/*引入基础设施,统一改为@wwjCommon/*(保证语义与边界一致)。 - 文档、示例与测试需统一遵循以上映射与规则;PR 不得混用别名语义。
- 禁止使用
-
预设入口与编译耦合(建议):
- 提供
preset.core(不含 AI)与preset.full(含 AI);应用可按业务选择以降低编译期耦合。
- 提供
-
i18n 软依赖与兜底:
- 拦截器与异常过滤器不强制注入
I18nService;未启用BootLangModule时返回msg_key。 - 参考
LANG-GUIDE.md的ModuleRef.get(I18nService, { strict:false })方案。
- 拦截器与异常过滤器不强制注入