yumi-flutter/docs/后端接口对接规范.md

18 KiB
Raw Blame History

Yumi Flutter 后端接口对接规范

适用仓库:yumi-flutter
后端代码:yumi-java + yumi-golang
最后核对2026-07-10

1. 目标与适用范围

本文档用于统一 Yumi Flutter 与 Java、Go 后端的接口对接方式,覆盖接口事实来源、路由归属、前端分层、响应解析、鉴权、错误处理、验证和问题流转。

核心原则:

  • 先查代码和配置,再实现;禁止根据页面或旧模型猜测后端契约。
  • Flutter 线程对两个后端仓库仅有只读权限,发现后端问题只记录证据和建议。
  • 所有业务 HTTP 请求必须经过项目现有网络层,页面不直接解析原始响应。
  • 接口失败时禁止使用本地假数据、硬编码列表或伪造成功结果还原页面。
  • Bug 修复必须先说明 Root Cause 和影响面,经确认后再做最小改动并提供验证证据。

2. 仓库位置与责任边界

2.1 Flutter 客户端

/Users/pinpaibu/flutter_code/yumi-flutter

当前技术和分层事实:

  • 网络Dio统一客户端为 lib/shared/data_sources/sources/remote/net/network_client.dart
  • 响应封装:ResponseData<T>
  • 仓储接口:lib/shared/business_logic/repositories/
  • 仓储实现:lib/shared/data_sources/sources/repositories/
  • 请求/响应模型:lib/shared/business_logic/models/req/res/
  • 功能模块:lib/modules/;独立功能也可在模块内保留 data/api/repository/models 边界,例如 lib/modules/room_game/data/
  • 页面状态Provider + ChangeNotifier全局管理器在 lib/services/
  • 路由Fluro入口为 lib/main.dart

2.2 Java 后端

/Users/pinpaibu/server_code/yumi-java

客户端相关的主要边界:

  • rc-gateway/Spring Cloud Gateway是 Flutter 默认 HTTP 入口。
  • nacos_config/rc-gateway/application.yml:外部路径到 Java/Go 服务的路由事实。
  • rc-auth/:登录凭证和内部 Token 校验。
  • rc-service/rc-service-other/:用户、配置、礼物、任务、房间外围等大量 App 业务。
  • rc-service/rc-service-live/:语音房在线、麦位等实时业务。
  • rc-service/rc-service-wallet/:钱包、余额、流水。
  • rc-service/rc-service-order/:订单与支付。
  • rc-service/rc-service-external/文件、短信、IM/TRTC 等外部能力。
  • rc-service/rc-inner-api/Java 服务内部 Feign 契约Flutter 不直接调用。

Java README.md 可用于快速定位模块,但其端口和模块说明可能滞后;联调时必须以 Gateway/Nacos 路由和当前 Controller 为准。

2.3 Go 后端

/Users/pinpaibu/server_code/yumi-golang

当前主要边界:

  • cmd/api/HTTP API 启动和依赖装配。
  • cmd/consumer/:事件消费入口。
  • internal/router/Gin 路由、请求绑定、鉴权中间件和统一响应。
  • internal/service/<module>/:按业务模块拆分的业务逻辑。
  • internal/integration/Go 调用 Java 服务的网关封装。
  • internal/common/AppErrorAuthUser 等跨模块类型。
  • internal/model/migrations/:表映射和数据库迁移。
  • internal/config/config.go:运行配置与 Java 下游地址。

Go 本地 HTTP 默认监听 :2900,但 Flutter 默认仍应通过 Java Gateway 访问,不应在业务代码中硬编码内部端口。


3. 后端仓库只读红线

在 Flutter 对接任务中,yumi-javayumi-golang 一律视为只读证据源。

允许:

  • 使用 rgfindsed -ngit status --shortgit diffgit show 查看和搜索。
  • 读取路由、Controller/Handler、DTO、Service、错误码、配置和测试。
  • 在 Flutter 文档中记录后端证据路径和待确认事项。

禁止:

  • 在后端仓库创建、修改、删除、移动或格式化任何代码、文档、配置、SQL、生成文件和测试。
  • 运行会产生文件的命令,如 gofmt -wgoimports -wgo mod tidy、Maven 打包、代码生成、数据库迁移。
  • 默认启动后端、Docker、消费者、定时任务或执行后端测试确有必要时必须先说明作用和文件/数据影响,并得到用户明确授权。
  • 在后端仓库执行暂存、提交、切分支、合并、拉取或推送。
  • 把调试标记或前端待办写入后端源码。

4. 实际请求拓扑与路由归属

4.1 默认链路

Flutter
  -> Java GatewayAPI_HOST
     -> Java auth / external / order / wallet / live / other
     -> Go API
        -> MySQL / Redis / MQ
        -> Java 内部服务(鉴权、用户、钱包、奖励等)

Flutter 默认基地址由 SCVariant1Config.apiHost 提供,可通过编译参数覆盖:

flutter run --dart-define=API_HOST=https://example-gateway/

不得在 Repository、Manager 或 Widget 中硬编码生产/测试域名。

4.2 Java Gateway 路由要点

yumi-java/nacos_config/rc-gateway/application.yml 为准,当前关键对外路径如下:

Flutter 请求路径 Gateway 处理 实际归属
/auth/** 去掉 /auth Java auth
/external/** 去掉 /external Java external
/order/** 去掉 /order Java order
/wallet/** 去掉 /wallet Java wallet
/live/** 去掉 /live Java live
/go/** 去掉 /go Go API
/app/game/** 保留原路径 Go API
未匹配的普通路径 默认转发 Java other
Req-Likei: true 的加密路由 ForwardRoute 解析后转发 由解析结果决定

Gateway 还对部分活动、回调和后台路径做了专用路由;对接具体接口时必须搜索完整 path不能只根据前缀推断服务归属。

4.3 Go 路径的两种对接形式

  • 经 Gateway 的 /go 路由Flutter 请求 /go/app/vip/statusGo 实际接收 /app/vip/status
  • Gateway 专用路由:例如 Flutter 请求 /app/game/providersGo 仍接收 /app/game/providers

除已有调试边界外,新增 App 接口优先使用同一 API_HOST 经 Gateway 访问。项目已有两个可选直连覆盖:

  • VIP_API_HOSTVIP Go API 调试。
  • GAME_API_HOST:房间游戏 Go API 调试。

仅在确认需要绕过 Gateway 联调时使用;不得为单个页面随意新增直连域名。


5. 接口事实参考顺序

当前两个后端仓库没有可覆盖全部 App 接口的统一 OpenAPI 契约,因此必须以可执行代码和当前路由配置为主证据。

5.1 先确定请求归属

  1. nacos_config/rc-gateway/application.yml 搜索完整 path 或前缀。
  2. 判断请求是否会 StripPrefix,记录 Flutter path 与下游 path。
  3. 确认该路由是否在 gateway.ignorePaths 中;“忽略 Gateway 鉴权”不等于“业务无需鉴权”,还要继续检查下游实现。

5.2 Java 接口

按以下顺序核对:

  1. *-adapter/src/main/java/**/**RestController.java@RequestMapping + @Get/Post/Put/DeleteMapping 确认 method/path。
  2. Controller 方法参数:确认 query/path/form/json、@Validated 和必填规则。
  3. *-client / *-inner 中的 Command、CO、DTO、Enum确认字段名、类型、枚举和响应数据。
  4. *-application 中对应 Service确认业务条件、空值和错误分支。
  5. 错误码枚举、ApiException 和统一响应框架:确认业务失败语义。
  6. 最后查看相关测试和 README/docs用于补充流程不用于覆盖当前代码。

5.3 Go 接口

按以下顺序核对:

  1. internal/router/<module>_routes.go:确认 method/path、鉴权中间件、query/path/body 绑定。
  2. internal/service/<module>/types.go 及对应业务文件:确认请求/响应字段、默认值、业务规则和 AppError
  3. internal/integration/:如业务依赖 Java确认实际下游 endpoint、Header 和数值转换。
  4. internal/model/migrations/internal/config/:仅用于理解字段来源、持久化和运行限制。
  5. *_test.go:核对边界值和已固化行为。

5.4 证据冲突时

  • Gateway 配置决定外部请求实际到达哪个服务。
  • 当前 Router/Controller 实现决定 method、path 和参数接收方式。
  • 当前 Service/DTO 实现决定业务语义和字段。
  • README、注释、历史文档和 Flutter 旧模型只是补充证据。
  • 冲突时以当前可到达的执行代码作为“现状事实”同时记录“待后端确认”Flutter 不自行改后端消除差异。

6. 已确认的网络契约

6.1 请求 Header

ApiInterceptor 会统一补充:

  • Authorization: Bearer <token>(本地存在 Token 时)
  • req-lang
  • req-imei
  • req-app-intel
  • req-client
  • req-sys-origin
  • Host
  • 已确认的加密路由才会添加 Req-Likei: true

对接时不得在 Widget/Manager 重复手工组装这些公共 Header也不得在代码或日志中写死 Token、密钥或完整鉴权数据。

Go App 路由的 authMiddleware 会读取 Bearer Token并调用 Java auth 校验凭证;因此 Go 接口鉴权仍与 Java 登录态一致。

6.2 Java/Go 兼容响应

Flutter ResponseData<T> 当前兼容两类字段:

{
  "status": true,
  "errorCode": 0,
  "errorCodeName": "",
  "errorMsg": "success",
  "body": {},
  "time": 0
}

以及:

{
  "code": 200,
  "message": "OK",
  "data": {}
}

Go writeOK / writeError 会同时输出 status/errorCode/errorMsg/bodycode/message/data 两套兼容字段。Flutter 解析规则为:

  • 数据优先读取 body,不存在时读取 data
  • 优先用 status 判定成败;缺失时,code == 0code == 200 视为成功。
  • 错误码读取 errorCodecode,错误信息读取 errorMsgmessage
  • HTTP 200 不代表业务成功,仍必须检查 envelope。
  • HTTP 4xx/5xx 与业务失败都必须进入明确错误状态。

新接口不得在页面层再实现一套 envelope 判定逻辑。

6.3 空响应

  • 只有后端契约明确表示成功无数据时,才允许使用可空泛型和 allowNullBody: true
  • 不得用 false0、空字符串或空列表掩盖本应返回对象的契约问题。
  • 列表本身合法为空时,空列表是真实业务结果,不是接口失败的替代值。

6.4 路径与加密路由

  • 旧接口在 Repository 中仍可能使用哈希形式的路由键,network_client.dart 会用 _localRouteOverrides 转为已知明文 path。
  • 新对接优先使用后端路由中已确认的明文 path不复制或自行生成哈希。
  • 若线上 Gateway 明确要求加密路由,必须先获得后端路由键/转发规则并在网络层集中处理,页面层不得设置 Req-Likei

7. Flutter 对接落地规范

7.1 分层责任

Widget / Page
  -> Provider / ChangeNotifier / Manager
     -> Repository abstraction
        -> Repository implementation / feature Api
           -> NetworkClient
              -> Java Gateway -> Java or Go
  • Widget / Page:只负责渲染、交互与发出意图;不直接调 Dio不解析 JSON。
  • Provider / ChangeNotifier / Manager:编排加载、成功、空态和错误状态,调用 Repository不处理原始 envelope。
  • Repository abstraction:定义业务语义明确的方法和返回类型。
  • Repository implementation / feature Api:定义 method/path/query/body调用 http.get/post/put/delete,完成 model 映射。
  • NetworkClient:统一 base URL、Header、Token、超时、envelope 和通用错误处理。

对现有模块增加接口时,优先延续该模块的已有分层,不为单个接口引入第二套网络或状态管理方案。

7.2 Model 与字段

  • 字段命名、类型、可空性、枚举值和时间单位必须有后端证据。
  • 后端 int64/Long 字段如可能以数字或数字字符串返回,只能在 Model 解析边界做兼容,不得在 Widget 中反复转换。
  • 时间字段必须明确是秒、毫秒还是 ISO-8601禁止通过数值长度猜测。
  • 金额、金币和比例必须确认单位与精度,不得在 UI 层暗中乘除。
  • 枚举未知值应有安全的“未知/不支持”分支,但不得把未知值伪装成某个已知业务类型。
  • 不在 Model 中根据页面需求虚构后端未返回的业务字段。

7.3 请求参数

  • GET 查询使用 queryParamspath variable 只用已确认的 URL 片段。
  • JSON 请求使用 data,参数命名与后端契约一致。
  • 文件上传使用 FormData/MultipartFile必须同时确认表单字段名、MIME、扩展名、大小上限和超时。
  • 幂等写操作的 key 由调用方在一次用户意图开始时创建,同一次超时重试必须复用;不得在每次底层请求时重新生成。
  • 分页必须记录是 cursor、page/size 还是 lastId不得混用。

7.4 错误和登录态

  • 网络层负责超时、HTTP 错误、通用业务错误和当前登录态校验。
  • Manager/Provider 只负责将错误转为页面可表达的错误状态,必要时提供重试入口。
  • Widget 不得看 errorCode 决定登出,不得自行重试鉴权失败。
  • 不得把服务端内部堆栈、SQL、密钥、完整 Token 或敏感请求体输出到生产日志。
  • 同一页面需要部分容错时,必须先定义每个数据源的独立成功/失败语义,不能用本地假数据补齐失败部分。

8. 严禁本地数据兜底

接口错误、超时、解析失败或返回不完整时,禁止:

  • 返回内置 mock 列表、本地 JSON、调试 assets 或硬编码对象。
  • 把异常转换为空列表、false0 或“成功”,使页面误以为接口已成功。
  • 因为新接口不可用而静默切换到语义不同的旧接口。
  • 用占位数据触发下游支付、送礼、发奖、扣费、房间状态或其他写操作。

允许的仅是产品明确设计的本地能力,例如:

  • 加载骨架、空态插图、错误提示和重试按钮,但不得表示为服务端真实数据。
  • 明确定义的离线缓存,但必须保留“旧数据/离线”语义,不能覆盖本次请求失败事实。
  • 纯 UI 预览和单元测试中的 Fake/Fixture必须与生产请求路径隔离。

9. 标准对接流程

  1. 明确本次业务范围,不顺手改无关模块。
  2. 在 Flutter 中搜索现有接口、Model、Manager 和测试,确认已有状态和兼容要求。
  3. 查 Java Gateway 路由,确定请求归属和外部 path。
  4. 按第 5 节读取 Java 或 Go 的 Router/Controller、DTO/Service、错误和测试。
  5. 先写一份接口事实记录,至少包含 method/path/auth/request/response/error/evidence。
  6. 说明改动对现有路由、网络层、登录态、模型和页面的影响;若为 Bug先提供 Root Cause 并等待用户确认。
  7. 在 Flutter 做能解决问题的最小变更,不重构无关代码。
  8. 增加 Model/envelope/分页/错误分支的针对性测试。
  9. 按第 11 节执行验证,并记录真实 API 联调结果。
  10. 如后端需要调整,只记录待确认项和证据,由用户协调后端处理。

10. 接口事实记录模板

### 接口名称

- 业务模块:
- 调用链路Flutter -> Java Gateway -> Java / Go -> 下游
- Flutter Method / Path
- 下游 Method / Path
- Gateway 路由处理:保留路径 / StripPrefix / 加密转发
- Auth无 / Bearer / 其他
- Request
  - path
  - query
  - header
  - body/form
- Response body/data
- 空值与默认值:
- 业务错误码:
- 时间/金额/分页/幂等语义:
- 后端证据:
  - Gateway
  - Router / Controller
  - DTO / Service
  - Test / Doc
- Flutter 落地:
  - repository/api
  - model
  - manager/provider
  - view
  - test
- 待后端确认:
- 当前状态:未对接 / 对接中 / 已对接 / 等后端

11. 验证规范

11.1 静态与自动化验证

只格式化本次改动的 Dart 文件,然后执行:

flutter analyze
flutter test

网络 envelope 或通用解析改动至少运行:

flutter test test/network_response_data_test.dart

业务 Model 改动应运行或新增对应 *_test.dart;不能只依赖 Widget 手工观察。

11.2 真实接口联调

至少验证:

  1. 实际请求 method/path 与 Gateway 转发后 path 正确。
  2. 需鉴权接口携带当前 Bearer Token无 Token/失效 Token 进入错误态。
  3. 成功、真实空数据、业务失败、HTTP 失败、超时、解析失败各至少覆盖相关分支。
  4. 重复点击、翻页、刷新和页面销毁不会产生重复写入或过期状态覆盖。
  5. 接口失败时页面不出现本地假数据,也不把失败当作空数据。
  6. 错误信息可理解、可重试,且日志不包含敏感信息。

11.3 回归影响

每次交付要明确说明:

  • 是否修改公共 NetworkClientResponseData、公共 Header 或 Token 处理。
  • 是否影响旧哈希路由、明文路由或 base URL override。
  • 是否影响其他共用 Model、Repository、Provider 或实时消息。
  • 针对上述影响执行了哪些测试,结果是什么。

12. 后端问题流转

出现以下情况时Flutter 不修改后端:

  • Gateway 路由与 Router/Controller 不一致。
  • Java/Go 响应字段、可空性、数值类型或枚举不一致。
  • HTTP 状态码、errorCode/code 和业务语义不能支持前端分支。
  • 鉴权、幂等、分页、排序、时区、时间单位或金额单位不清晰。
  • Go 路由存在但 Java Gateway 没有可到达转发。
  • 后端仅有占位实现、返回 mock或所需下游能力未上线。

记录模板:

- 【待后端确认业务模块YYYY-MM-DD HH:mm CST】
  问题:
  现象:
  证据:
    - Gateway
    - Java / Go
    - Flutter
  Root Cause 判断:
  前端影响:
  建议后端处理:
  联调验收条件:

13. 文档维护要求

  • 本文档记录稳定规则;具体接口事实应写入对应业务文档,避免把本文档变成无法维护的接口大全。
  • 引用后端证据时写明仓库和相对路径,必要时补充类/函数名,不复制大段实现。
  • 不在文档中记录真实 Token、密码、密钥、DSN、云服务凭证或内网敏感信息。
  • 后端路由或响应契约变更后,同步更新相关业务接口记录和验证日期。
  • 文档中的“已对接”必须同时满足Flutter 代码已落地、自动化验证通过、真实接口联调通过、不存在本地假数据兜底。