18 KiB
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/:AppError、AuthUser等跨模块类型。internal/model/与migrations/:表映射和数据库迁移。internal/config/config.go:运行配置与 Java 下游地址。
Go 本地 HTTP 默认监听 :2900,但 Flutter 默认仍应通过 Java Gateway 访问,不应在业务代码中硬编码内部端口。
3. 后端仓库只读红线
在 Flutter 对接任务中,yumi-java 和 yumi-golang 一律视为只读证据源。
允许:
- 使用
rg、find、sed -n、git status --short、git diff、git show查看和搜索。 - 读取路由、Controller/Handler、DTO、Service、错误码、配置和测试。
- 在 Flutter 文档中记录后端证据路径和待确认事项。
禁止:
- 在后端仓库创建、修改、删除、移动或格式化任何代码、文档、配置、SQL、生成文件和测试。
- 运行会产生文件的命令,如
gofmt -w、goimports -w、go mod tidy、Maven 打包、代码生成、数据库迁移。 - 默认启动后端、Docker、消费者、定时任务或执行后端测试;确有必要时必须先说明作用和文件/数据影响,并得到用户明确授权。
- 在后端仓库执行暂存、提交、切分支、合并、拉取或推送。
- 把调试标记或前端待办写入后端源码。
4. 实际请求拓扑与路由归属
4.1 默认链路
Flutter
-> Java Gateway(API_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/status,Go 实际接收/app/vip/status。 - Gateway 专用路由:例如 Flutter 请求
/app/game/providers,Go 仍接收/app/game/providers。
除已有调试边界外,新增 App 接口优先使用同一 API_HOST 经 Gateway 访问。项目已有两个可选直连覆盖:
VIP_API_HOST:VIP Go API 调试。GAME_API_HOST:房间游戏 Go API 调试。
仅在确认需要绕过 Gateway 联调时使用;不得为单个页面随意新增直连域名。
5. 接口事实参考顺序
当前两个后端仓库没有可覆盖全部 App 接口的统一 OpenAPI 契约,因此必须以可执行代码和当前路由配置为主证据。
5.1 先确定请求归属
- 在
nacos_config/rc-gateway/application.yml搜索完整 path 或前缀。 - 判断请求是否会
StripPrefix,记录 Flutter path 与下游 path。 - 确认该路由是否在
gateway.ignorePaths中;“忽略 Gateway 鉴权”不等于“业务无需鉴权”,还要继续检查下游实现。
5.2 Java 接口
按以下顺序核对:
*-adapter/src/main/java/**/**RestController.java:@RequestMapping+@Get/Post/Put/DeleteMapping确认 method/path。- Controller 方法参数:确认 query/path/form/json、
@Validated和必填规则。 *-client/*-inner中的 Command、CO、DTO、Enum:确认字段名、类型、枚举和响应数据。*-application中对应 Service:确认业务条件、空值和错误分支。- 错误码枚举、
ApiException和统一响应框架:确认业务失败语义。 - 最后查看相关测试和 README/docs,用于补充流程,不用于覆盖当前代码。
5.3 Go 接口
按以下顺序核对:
internal/router/<module>_routes.go:确认 method/path、鉴权中间件、query/path/body 绑定。internal/service/<module>/types.go及对应业务文件:确认请求/响应字段、默认值、业务规则和AppError。internal/integration/:如业务依赖 Java,确认实际下游 endpoint、Header 和数值转换。internal/model/、migrations/和internal/config/:仅用于理解字段来源、持久化和运行限制。*_test.go:核对边界值和已固化行为。
5.4 证据冲突时
- Gateway 配置决定外部请求实际到达哪个服务。
- 当前 Router/Controller 实现决定 method、path 和参数接收方式。
- 当前 Service/DTO 实现决定业务语义和字段。
- README、注释、历史文档和 Flutter 旧模型只是补充证据。
- 冲突时以当前可到达的执行代码作为“现状事实”,同时记录“待后端确认”,Flutter 不自行改后端消除差异。
6. 已确认的网络契约
6.1 请求 Header
ApiInterceptor 会统一补充:
Authorization: Bearer <token>(本地存在 Token 时)req-langreq-imeireq-app-intelreq-clientreq-sys-originHost- 已确认的加密路由才会添加
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/body 与 code/message/data 两套兼容字段。Flutter 解析规则为:
- 数据优先读取
body,不存在时读取data。 - 优先用
status判定成败;缺失时,code == 0或code == 200视为成功。 - 错误码读取
errorCode或code,错误信息读取errorMsg或message。 - HTTP 200 不代表业务成功,仍必须检查 envelope。
- HTTP 4xx/5xx 与业务失败都必须进入明确错误状态。
新接口不得在页面层再实现一套 envelope 判定逻辑。
6.3 空响应
- 只有后端契约明确表示成功无数据时,才允许使用可空泛型和
allowNullBody: true。 - 不得用
false、0、空字符串或空列表掩盖本应返回对象的契约问题。 - 列表本身合法为空时,空列表是真实业务结果,不是接口失败的替代值。
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 查询使用
queryParams,path 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 或硬编码对象。
- 把异常转换为空列表、
false、0或“成功”,使页面误以为接口已成功。 - 因为新接口不可用而静默切换到语义不同的旧接口。
- 用占位数据触发下游支付、送礼、发奖、扣费、房间状态或其他写操作。
允许的仅是产品明确设计的本地能力,例如:
- 加载骨架、空态插图、错误提示和重试按钮,但不得表示为服务端真实数据。
- 明确定义的离线缓存,但必须保留“旧数据/离线”语义,不能覆盖本次请求失败事实。
- 纯 UI 预览和单元测试中的 Fake/Fixture,必须与生产请求路径隔离。
9. 标准对接流程
- 明确本次业务范围,不顺手改无关模块。
- 在 Flutter 中搜索现有接口、Model、Manager 和测试,确认已有状态和兼容要求。
- 查 Java Gateway 路由,确定请求归属和外部 path。
- 按第 5 节读取 Java 或 Go 的 Router/Controller、DTO/Service、错误和测试。
- 先写一份接口事实记录,至少包含 method/path/auth/request/response/error/evidence。
- 说明改动对现有路由、网络层、登录态、模型和页面的影响;若为 Bug,先提供 Root Cause 并等待用户确认。
- 在 Flutter 做能解决问题的最小变更,不重构无关代码。
- 增加 Model/envelope/分页/错误分支的针对性测试。
- 按第 11 节执行验证,并记录真实 API 联调结果。
- 如后端需要调整,只记录待确认项和证据,由用户协调后端处理。
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 真实接口联调
至少验证:
- 实际请求 method/path 与 Gateway 转发后 path 正确。
- 需鉴权接口携带当前 Bearer Token,无 Token/失效 Token 进入错误态。
- 成功、真实空数据、业务失败、HTTP 失败、超时、解析失败各至少覆盖相关分支。
- 重复点击、翻页、刷新和页面销毁不会产生重复写入或过期状态覆盖。
- 接口失败时页面不出现本地假数据,也不把失败当作空数据。
- 错误信息可理解、可重试,且日志不包含敏感信息。
11.3 回归影响
每次交付要明确说明:
- 是否修改公共
NetworkClient、ResponseData、公共 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 代码已落地、自动化验证通过、真实接口联调通过、不存在本地假数据兜底。