front/docs/下游接口明细改造方案-小改vs大改.md
2026-06-04 19:15:28 +08:00

17 KiB
Raw Blame History

下游接口明细改造方案:小改 vs 大改

场景:下游接口页(/api/downstreamInterface)保存接口明细时,需要更好支持 FormUrlEncoded / 表单类接口 中「某个字段的值是一整段 JSON」的情况。
目标:为上游映射提供独立的 Mapping Body(映射体) 结构树,表单字段用 $FromMappingBody 引用映射结果。
参考 UI:/api/apiDebugger(ApiTest:Query / Request(Body) / Header)。


1. 现状速览(为何需要改)

层级 现状 问题
表 t_parameter(IsInPara)= 入参树;t_parameter_form(无位置)= 表单 KV;t_parameter_fixed(FieldPositions)= 固定 Header/Query/Body 前端「Query」Tab 实际写的是 formParameterList,后端却只把 Form 当 整段 x-www-form-urlencoded Body,不是 URL Query
页面 InterfaceDetail:Query(表单) + Body(参数树) + 固定配置 + cURL 与 ApiTest 的 Query/Body/Header 不一致;Body 树同时承担「HTTP JSON 结构」和「上游映射主体」,表单里 JSON 字段只能塞 $FromBody,语义混
转发 InParamRestructure ← 下游 IsInPara 树;FormFieldList ← 全部 form;Query/Header ← FixedFieldList 映射树与传输层表单未分离
上游 JSON ──► InParamRestructure(下游 IsInPara 树) ──► OriginalInterfaceMappedInput
                    │
                    ▼
              ReplacePlaceholder / 序列化
                    │
                    ▼
         FormUrlEncoded(form 全进 Body)+ Fixed(Query/Header)

2. 方案总览

维度 方案 A:小改(推荐优先) 方案 B:大改(完全对齐 ApiTest)
核心思路 只新增 Mapping Body 参数树 + $FromMappingBody,其余结构基本不动 Query/Body/Header 表单分表存储 + 转发按位置组装;Mapping Body 独立;逐步弱化「固定配置」与旧 form 语义
表变更 1 张表加 1 个字段(或 1 个枚举列) 至少 2 张表扩展 + 数据迁移 + 行为重构
API 变更 SaveInterface / GetInterfaceById 增字段;占位符枚举增 1 项 契约重组(多列表/统一带 position);Fixed 与 Form 职责重划
转发逻辑 映射树数据源切换 + 占位符分支(约数十行级) RequestAsync / SetContentType / 缓存 / 映射 SQL 全链路调整
前端 InterfaceDetail 增 1 个 Tab,保存多传一个列表 整页 Request 区重写,对齐 ApiTest;curl 填充、映射页联动
风险 低,可灰度、可回滚 中高,影响所有下游接口与发布数据
工期(粗估) 后端 2~4 人日 + 前端 3~5 人日 后端 8~15 人日 + 前端 10~18 人日 + 联调/迁移

3. 方案 A:小改(Mapping Body 增量)

3.1 要解决什么

只解决:Query/Body 表单里某字段值为 JSON(或应填 $FromBody)时,上游映射应对的是 JSON 内部结构,而不是把整段 form 或错误树当映射目标。

不解决(保持现状):

  • Form 仍整体作为 FormUrlEncoded Body(不拆真正的 URL Query 表单 Tab 行为)
  • Header 仍主要走 固定配置(FixedParameter)
  • ContentType=Json 的下游接口仍用现有 inParameterList 作 Body + 映射(可不显示 Mapping Body Tab)

3.2 表结构

表 变更 说明
t_parameter 新增 ParaKind(int)或 IsMappingBody(bit) 0=Normal(现有入参/出参逻辑),1=MappingBody(仅映射,不参与 Json 序列化 Body 时可配置策略)
t_parameter_form 不改 仍 flat KV;JSON 字段 value 改为 $FromMappingBody
t_parameter_fixed 不改 Header/Query 固定值照旧

迁移:历史数据 ParaKind=0;原 inParameterList 若实为映射树,可脚本把「仅用于 FormUrlEncoded 映射」的接口标为 MappingBody,或 读时兼容(见下)。

3.3 接口契约

GET Interface/GetInterfaceById

{
  "inParameterList": [],
  "mappingBodyParameterList": [],
  "formParameterList": [],
  "outParameterList": []
}

兼容规则:

  • 若 mappingBodyParameterList 为空 → 用 inParameterList 填充(老数据零感知)
  • 新保存的 FormUrlEncoded 接口:映射树写 mappingBodyParameterList,inParameterList 可留空或仅存「真实 HTTP JSON Body 结构」(Json 类型仍用 in)

POST Interface/SaveInterface

{
  "mappingBodyParameterList": [{ "optionType": 1, "id": 1, "pId": 0, "name": "order", "alias": "order", "type": 3 }],
  "inParameterList": [],
  "formParameterList": [
    { "name": "notifyBizEventDTO", "value": "$FromMappingBody", "optionType": 0 }
  ]
}

inParameterList / outParameterList / formParameterList 字段 保留,老前端、导入导出可继续用。

其它接口

接口 变更
Dictionary/GetList?type=ParameterPlaceholder 后端枚举加 FromMappingBody → 展示 $FromMappingBody
InterfaceMap/*(映射编辑) 下游入参映射 SQL/列表 优先 ParaKind=MappingBody,无则回退 IsInPara
FixedParameter/* 无
FormParameter/GetParameterList 无

3.4 后端逻辑改动点

模块 改动量 内容
ParameterService / InterfaceService 小 保存/读取时按 ParaKind 过滤;维护 MappingBody 列表
InterfaceForwardQuery.GetParameterMapListAsync 小 JOIN t_parameter 增加 ParaKind=MappingBody 条件(入参映射)
InterfaceForwardQuery 构建 InParamTreeList 小 有 MappingBody 用其建树,否则用原 IsInPara
DefaultForwardFlow.ReplacePlaceholder 小 FixedFieldList / FormFieldList 增加 $FromMappingBody → Serialize(OriginalInterfaceMappedInput)
DefaultForwardFlow.SetContentType 小 FormUrlEncoded 里对 $FromMappingBody 与 $FromBody 同样替换为序列化结果(可共用实现)
DefaultForwardFlow.RequestAsync 无或极小 不拆 Query/Header 表单
ServiceProviderImportExportService 小 导出/导入带上 ParaKind
发布缓存 ForwardCoreContextCache 小 缓存参数列表带 ParaKind

$FromBody vs $FromMappingBody(小改语义建议)

占位符 小改建议语义
$FromBody 保持现有行为(兼容老配置)
$FromMappingBody 明确指向 OriginalInterfaceMappedInput 的序列化(映射完成后、写进 form 字段)

3.5 前端改动点

文件/模块 改动量
InterfaceDetail 中:Request 区增加 Mapping Body Tab(复用现有 Body 树表格);原 Body Tab 可改名为「传输 Body」或保留树仅给 Json 类型显示
ServiceProviderInterfaceModal.saveInterface 小:多组装 mappingBodyParameterList;formParameterList 仍只来自 Query 表
curlToInterfaceFill 小:JSON 类 form 字段推断 $FromMappingBody
upstreamInterfaceConfig 映射页 小:下游参数源改读 mapping 列表(后端改即可)
itfxEnums / 文档 小
ApiTest 无

3.6 方案 A 优点 / 缺点

优点

  • 改动面可控,只增加概念,不推翻 Form/Fixed 分工
  • 老接口、老映射、老占位符可继续跑
  • 符合「多的映射 body 只解决表单里还有 json」的诉求

缺点

  • UI 仍与 ApiTest 不完全一致(Query 名不副实、Header 仍在固定配置)
  • 技术债仍在:formParameterList ≠ URL Query

4. 方案 B:大改(完全对齐 API 调试)

4.1 目标结构(与 ApiTest 一致)

┌─ 基本信息(地址、Method、ContentType…)────────────────┐
├─ Query    KV 表  → 真实 URL Query                         │
├─ Body     KV 表  → Form Body / 或 Raw(按 ContentType)   │
├─ Header   KV 表  → 请求头                                 │
├─ Mapping Body  参数树 → 仅上游映射主体($FromMappingBody) │
├─ Response 参数树 + 返回配置(保持)                        │
└─ cURL 示例(可选)                                        ┘

传输层(Query/Body/Header)与映射层(Mapping Body)彻底分离。

4.2 表结构

表 变更 说明
t_parameter_form 新增 FieldPosition(int,enum:Header=1, Body=2, Query=3) 一条 form 记录明确归属;历史数据默认 Body=2
t_parameter 新增 ParaKind(Normal / MappingBody / 可选 TransportBody) MappingBody 只用于映射;Json 接口的 HTTP Body 树可用 Normal 或单独 Kind
t_parameter_fixed 可选废弃或降级 Header/Query 迁入 form 后,Fixed 仅保留服务商级 / Url 路径 / 脚本写入项;需迁移工具
t_interface 一般不改 —

数据迁移

  • 旧 formParameterList → FieldPosition=Body
  • 旧 inParameterList(Form 场景)→ 拆到 MappingBody + 清空 in 或保留 Json 专用
  • 旧 FixedParameter(Header/Query)→ 迁入 t_parameter_form 或双写过渡期

4.3 接口契约(重组)

GetInterfaceById(示例)

{
  "queryFormParameterList": [],
  "bodyFormParameterList": [],
  "headerFormParameterList": [],
  "mappingBodyParameterList": [],
  "inParameterList": [],
  "outParameterList": [],

  "formParameterList": []
}

formParameterList 兼容期 = 三表合并;新前端只认分列表。

SaveInterface

  • 必传:queryFormParameterList + bodyFormParameterList + headerFormParameterList + mappingBodyParameterList + outParameterList
  • inParameterList:仅 ContentType=Json 时作为 HTTP JSON Schema(或合并进 mapping,产品需二选一)

其它

能力 大改影响
FixedParameter/MaintainParameter 接口明细页可能 移除 或仅服务商维度保留
授权 ServiceProviderAuth 入参列表来源可能改为 MappingBody
接口映射发布/对比 参数树 diff 逻辑调整
导入导出 全量适配 position + ParaKind
前置脚本 Skill FormFieldList 分 position;文档重写

4.4 后端逻辑改动点

模块 改动量 内容
FormParameterService 大 CRUD 带 FieldPosition;按 position 查询
InterfaceService Save/Get 大 多列表合并/拆分
DefaultForwardFlow.RequestAsync 大 FormFieldList 按 Query → UriBuilder.Query;Header → msg.Headers;Body → SetContentType
DefaultForwardFlow 与 Fixed 合并 大 同名冲突策略、服务商级覆盖规则
InterfaceForwardQuery 大 映射、授权、缓存多处
InterfaceMapRepository SQL 中 下游参数过滤 MappingBody
ServiceProviderImportExportService 大
单元/集成测试 大 需覆盖 Json / FormUrlEncoded / 混合 Header

4.5 前端改动点

模块 改动量
InterfaceDetail 很大:Request 区 Tabs 与 ApiTest 同构;删除或隐藏「固定配置」;三份 KV 表 + Mapping Body 树
ServiceProviderInterfaceModal 大:保存/加载拆 4 类参数
ApiTest 中:可抽公共组件 RequestTabs 复用
curlToInterfaceFill 大:-H→header,?query→query,--data→body form 或 mapping
downstreamInterface/index 中
upstreamInterface 小~中:上游是否展示 Mapping Body
newPort.vue 等历史页 中:废弃或同步

4.6 方案 B 优点 / 缺点

优点

  • 产品、开发、运维认知与 API 调试 一致,培训成本低
  • Query/Header 行为正确,不再名不副实
  • 映射与传输分层清晰,后续扩展 FormData、Raw Body 更自然

缺点

  • 改动面大:表 + 转发 + 映射 + 导入导出 + 多页面
  • 必须做 数据迁移与发布回归,线上 Form 接口需逐个验证
  • 与「只为表单 JSON 加一个映射体」相比,投入不成比例(若 80% 接口是 Json Body)

5. 改动量对照(文件级清单)

5.1 后端 itfx-master(约)

路径/模块 方案 A 方案 B
ParameterEntity + 迁移 SQL ● ●●
FormParameterEntity + 迁移 — ●●
SaveInterfaceInput / InterfaceOutput ● ●●
InterfaceService ● ●●
ParameterService ● ●●
FormParameterService — ●●
DefaultForwardFlow ● ●●●
InterfaceForwardQuery ● ●●
InterfaceMapRepository / InterfaceMapService ● ●●
ServiceProviderImportExportService ● ●●
GlobalConst / ParameterPlaceholder ● ●
ServiceProviderAuthService ○ ●
测试项目 ● ●●●

图例:— 无 ○ 可选 ● 必改 ●● 重度 ●●● 重构

5.2 前端 oms0414(约)

路径/模块 方案 A 方案 B
InterfaceDetail/index.vue ●● ●●●
ServiceProviderInterfaceModal.vue ● ●●
curlToInterfaceFill.ts ● ●●
constants/itfxEnums.ts + docs/itfx枚举说明.md ● ●●
api/InterfaceServices/typings.d.ts ● ●●
上游映射配置页 ● ●●
ApiTest/index.vue(抽组件) — ●●
downstreamInterface/newPort.vue ○ ●●

6. 行为对比(典型:1688 / FormUrlEncoded)

步骤 现状 方案 A 方案 B
定义 JSON 订单结构 写在 Body 参数树 写在 Mapping Body 树 同 A
表单字段 notifyBizEventDTO $FromBody $FromMappingBody $FromMappingBody(在 Body 表单 Tab)
URL ?a=1 Fixed Query 或没有 仍 Fixed / 没有 Query 表单 Tab
Header sign 固定配置 + 脚本 同左 Header 表单 Tab
上游映射配置 对下游 in 树 alias 对 MappingBody alias 同 A

7. 选型建议

                    表单 JSON 映射问题
                           │
           ┌───────────────┴───────────────┐
           │                               │
    仅 FormUrlEncoded 等少数接口          希望全站 UI/行为
    需要拆映射体                          与 ApiTest 完全一致
           │                               │
           ▼                               ▼
      【方案 A 小改】                  【方案 B 大改】
      优先落地、可迭代                 单独立项、版本窗口
若你的情况是… 建议
主要痛点是「form 里 JSON 字段 + 上游映射对不上」 方案 A
同时要强改 Query/Header 配置方式、去掉固定配置双轨 方案 B(或 A 上线后再做 B 的第二阶段)
资源紧、要先上线 A;B 里「form 分 position」可单独立项

推荐路径:先做方案 A → 验证 $FromMappingBody + 映射发布 → 若仍纠结 Query/Header 体验,再开 方案 B 第二阶段(只迁 t_parameter_form.FieldPosition + RequestAsync,Mapping Body 不再动)。


8. 方案 A 实施 checklist(可直接拆任务)

  • DB:t_parameter.ParaKind + 默认值
  • 实体/DTO/枚举:ParameterPlaceholder.FromMappingBody
  • GetInterfaceById / SaveInterface 增加 mappingBodyParameterList + 兼容
  • InParamTreeList / 映射 SQL 使用 MappingBody
  • DefaultForwardFlow 占位符
  • 导入导出
  • 前端 Mapping Body Tab + 保存字段
  • curl 智能填充推断 $FromMappingBody
  • 文档 itfx枚举说明.md 更新
  • 选 1~2 个 FormUrlEncoded 生产接口回归 + 发布

9. 方案 B 实施 checklist(摘要)

  • 产品定稿:Json 接口 in 树 vs MappingBody 分工;Fixed 是否保留
  • DB 迁移脚本 + 回滚脚本
  • Form 分 position 全链路
  • RequestAsync 三分支组装
  • 接口契约 v2(可 /Interface/SaveInterfaceV2 并行一期)
  • 前端 InterfaceDetail 重写 + 组件抽取
  • 映射/授权/导出/发布全量回归
  • 灰度:按服务商或接口标签切换

10. 附录:与 API 调试(ApiTest)结构对齐度

能力 ApiTest 现状 方案 A 方案 B
Query KV ✅ ⚠️ 名是 Query 实为 form ⚠️ ✅
Body KV / Raw ✅ ⚠️ 树在 Body ⚠️ form 仍在 Query 表 ✅
Header KV ✅ ⚠️ 在固定配置 ⚠️ ✅
映射 JSON 结构 — ⚠️ 混在 in 树 ✅ Mapping Body ✅
$FromMappingBody — ❌ ✅ ✅

文档版本:2026-06-02 · 基于 itfx-master + oms0414 下游接口/ApiTest 代码梳理