15 KiB
我会对照方案读取现有接口保存、参数实体和转发组装代码,判断改造影响面与风险点。
Created 4 todos
Searched for files matching **/src/InterfaceForward.Repositories/**/*.cs, 80 matches
我会并行读取关键实体、DTO、保存查询服务和转发构建代码,形成可行性判断。
Searched for files matching **/src/**/FixedParameter*.cs, 5 matches
我已读取实体和 DTO,下一步查看保存/查询接口与转发上下文构建,判断方案 B 的改动点是否闭环。
我继续读取上下文构建和映射查询代码,确认方案里 InParamTreeList 来源切换的实现难度。
关键转发查询显示目前仍把下游所有 IsInPara=true 当映射树,且 Form KV 未区分 Query/Header/Body;我再查看 DTO/枚举常量后给出结论。
Searched for regex enum FieldPosition|enum ContentType|FromBody|FromMappingBody|FormFieldList|FixedFieldList (**/src/**), 79 results
已有 FieldPosition 和 ContentType 枚举基本符合方案,但 t_parameter_form 实体缺 FieldPosition,t_parameter 缺 ParaKind,这是数据库层主要增量。
Completed: 梳理现有数据模型 (1/4)
可行,但这是中大型重构,不是小改。方案 B 和当前代码方向一致,主要是把现在“下游入参树 + 表单参数 + 固定参数”混用的问题拆清楚。建议可以做,但要按阶段推进。
总体结论
可行性:高。
改造成本:中高。
主要风险:映射保存/发布缓存/转发组装三处需要同步改,否则容易出现保存成功但转发错误。
方案 B 的核心改动和现有代码冲突点主要有 3 个:
- 当前下游统一使用
InParameterList作为映射树。 - 当前
t_parameter_form没有FieldPosition,无法区分 Query / Header / Body。 - 当前转发时 FormUrlEncoded 用
$FromBody,方案要求改成$FromMappingBody。
当前代码现状
1. t_parameter 当前只有 IsInPara
实体在 ParameterEntity.cs:
public bool IsInPara { get; set; }
目前语义是:
IsInPara = true:入参IsInPara = false:出参
但方案 B 需要进一步区分:
- 上游入参
- 下游 Json/Xml RequestBody
- 下游 FormUrlEncoded MappingBody
- 出参
所以需要新增:
public ParameterParaKind ParaKind { get; set; }
或类似枚举:
public enum ParameterParaKind
{
Normal = 0,
MappingBody = 1
}
2. t_parameter_form 当前没有 FieldPosition
实体在 FormParameterEntity.cs,当前只有:
public string Name { get; set; }
public string Value { get; set; }
public string Description { get; set; }
方案 B 要它承载:
- Query KV
- Header KV
- Body KV
所以必须新增:
public FieldPosition FieldPosition { get; set; }
现有 FieldPosition 枚举已经存在于 FieldPosition.cs,可直接复用。
3. SaveInterfaceInput 当前字段不够
当前 SaveInterfaceInput.cs 只有:
public List<ParameterInput> InParameterList { get; set; }
public List<ParameterInput> OutParameterList { get; set; }
public List<FormParameterInput> FormParameterList { get; set; }
方案 B 要改成:
public List<FormParameterInput> QueryFormParameterList { get; set; }
public List<FormParameterInput> HeaderFormParameterList { get; set; }
public List<FormParameterInput> BodyFormParameterList { get; set; }
public List<ParameterInput> InParameterList { get; set; }
public List<ParameterInput> RequestBodyParameterList { get; set; }
public List<ParameterInput> MappingBodyParameterList { get; set; }
public List<ParameterInput> OutParameterList { get; set; }
不做旧字段兼容的话,这个改动是合理的。
转发逻辑可行性
当前链路
当前构建转发上下文在 InterfaceForwardQuery.cs:
var inParaMaps = await GetParameterMapListAsync(mapIds, true);
...
InParamTreeList = JsonHelper.BuildTreeList(items)
FormFieldList = await GetFormFieldListAsync(targetInterface.Id)
FixedFieldList = fixedFieldList
当前问题是:
- 下游所有
IsInPara=true都被当成映射目标。 - FormUrlEncoded 和 Json 的映射树没有语义区分。
- Query/Header 主要还依赖
FixedFieldList或旧FormFieldList。
方案 B 的调整是可落地的:
| ContentType | InParamTreeList 来源 |
|---|---|
| Json / Xml | requestBodyParameterList |
| FormUrlEncoded | mappingBodyParameterList |
| 上游 | inParameterList |
这需要改 GetParameterMapListAsync() 查询条件:
- Json/Xml:查
t_parameter.IsInPara = true AND ParaKind = Normal - FormUrlEncoded:查
t_parameter.IsInPara = true AND ParaKind = MappingBody - 出参:仍查
IsInPara = false
HTTP 组装改造可行性
当前 DefaultForwardFlow.cs 已经有这些能力:
- Query 拼接
- Header 拼接
- FormUrlEncoded Body 组装
- Json/XML Body 序列化
- 占位符替换
所以不是推倒重来,而是调整来源。
当前 FormUrlEncoded
当前逻辑大致是:
if (context.FormFieldList.Count != 0)
{
var field = context.FormFieldList.FirstOrDefault(x => x.Value == GlobalConst.FromBody);
if (field != null) field.Value = body;
nameValueCollection = context.FormFieldList.ToDictionary(x => x.Name, x => x.Value);
}
方案 B 要改为:
$FromMappingBody
并且 FormFieldList 只取 FieldPosition = Body。
Query/Header 不应该混在 FixedFieldList 的接口级配置里,而应来自:
queryFormParameterList
headerFormParameterList
数据库改造建议
需要新增字段:
t_parameter_form
ALTER TABLE t_parameter_form
ADD FieldPosition INT NOT NULL DEFAULT 2;
默认 2 = Body,这样老数据如果不迁移也能先当 Body。
t_parameter
ALTER TABLE t_parameter
ADD ParaKind INT NOT NULL DEFAULT 0;
默认 0 = Normal。
如果真的“不做旧字段兼容,全量重构”,可以不迁移旧语义;但数据库字段还是要加。
主要影响面
必改
| 模块 | 文件/区域 | 影响 |
|---|---|---|
| DTO | SaveInterfaceInput |
入参结构重构 |
| DTO | FormParameterInput |
新增 FieldPosition |
| DTO | ParameterInput |
新增 ParaKind |
| Entity | FormParameterEntity |
新增 FieldPosition |
| Entity | ParameterEntity |
新增 ParaKind |
| SaveInterface | InterfaceService |
按 ContentType 互斥保存 |
| GetInterfaceById | InterfaceService |
按 ContentType 拆分返回 |
| 参数服务 | ParameterService |
保存/查询支持 ParaKind |
| 表单服务 | FormParameterService |
保存/查询支持 FieldPosition |
| 转发查询 | InterfaceForwardQuery |
映射树按 ContentType 选择 |
| 转发执行 | DefaultForwardFlow |
$FromMappingBody、Query/Header/Form 来源调整 |
可能要改
| 模块 | 原因 |
|---|---|
InterfaceMapService |
映射页面可能依赖下游 InParameterList |
InterfaceMapPublishService |
发布缓存构建依赖参数树 |
FixedParameterService |
方案要求删除接口级 Fixed 维护 |
| 导入导出 | 如果导出接口配置,需要更新结构 |
| 脚本助手 | 需要支持 $FromMappingBody 和新的 Query/Header/Body 结构 |
最大风险点
1. 映射页面风险最高
当前映射保存结构在 SaveParameterMapsInput.cs。
它的 ParaId 指向下游参数。
方案 B 后:
- Json/Xml 下游:
ParaId指向requestBodyParameterList - FormUrlEncoded 下游:
ParaId指向mappingBodyParameterList - Header/Query/BodyForm KV 不参与普通参数映射,除非值为
$FromMappingBody
这个规则必须前后端统一,否则映射会乱。
2. 缓存风险
转发上下文会缓存:
ForwardContext:up_{upStreamCode}:sp_{serviceProviderCode}
重构后发布接口/保存接口必须清理或重建缓存,否则会拿旧结构转发。
3. FormUrlEncoded 行为变化
旧逻辑用 $FromBody,新逻辑用 $FromMappingBody。
如果现有表单配置里已经有 $FromBody,全量重构可以不兼容,但测试环境必须重新配置。
4. 接口级 Fixed 删除要谨慎
t_parameter_fixed 当前支持:
ServiceProviderId
InterfaceId
方案要求删除接口级 Fixed 维护,但代码里 InterfaceForwardQuery.cs 仍会查:
a.ServiceProviderId == serviceProviderId || a.InterfaceId == interfaceId
如果彻底删除接口级 Fixed,需要改成只查服务商级:
a.ServiceProviderId == serviceProviderId
否则旧数据仍会生效。
推荐实施顺序
第一阶段:数据模型和 DTO
- 新增
ParameterParaKind枚举。 ParameterEntity新增ParaKind。ParameterInput新增ParaKind。FormParameterEntity新增FieldPosition。FormParameterInput/FormParameterItem新增FieldPosition。SaveInterfaceInput拆分字段。
第二阶段:保存/查询接口
改 InterfaceService.cs:
- 上游:只保存
inParameterList - 下游 Json/Xml:只保存
requestBodyParameterList - 下游 FormUrlEncoded:保存
bodyFormParameterList+mappingBodyParameterList - 所有类型:保存
queryFormParameterList+headerFormParameterList - 所有类型:保存
outParameterList
并加入互斥校验。
第三阶段:转发查询
改 InterfaceForwardQuery.cs:
GetParameterMapListAsync()支持ParaKindGetFormFieldListAsync()改成按FieldPosition获取- 构建
TargetInterfaceSummary时区分:QueryFieldListHeaderFieldListBodyFormFieldListInParamTreeList
第四阶段:转发执行
改 DefaultForwardFlow.cs:
ReplacePlaceholder()支持$FromMappingBody- Query 从 Query KV 来
- Header 从 Header KV 来
- FormUrlEncoded Body 从 Body KV 来
- Json/Xml Body 保持序列化
OriginalInterfaceMappedInput
第五阶段:映射与发布
重点改:
- 映射详情查询
- 映射保存
- 发布缓存
- 缓存清理
第六阶段:测试
建议新增测试覆盖:
- 下游 Json:
requestBodyParameterList映射并序列化为 JSON。 - 下游 Xml:
requestBodyParameterList映射并序列化为 XML。 - FormUrlEncoded:
mappingBodyParameterList映射,bodyFormParameterList中$FromMappingBody被替换。 - Query:所有 ContentType 都能拼 Query。
- Header:所有 ContentType 都能加 Header。
- 上游:仍只使用
inParameterList。 - 接口级 Fixed 不再生效。
- 服务商级 Fixed 仍生效。
可行性评级
| 项 | 评级 |
|---|---|
| 技术可行性 | 高 |
| 代码改动量 | 中高 |
| 数据库改动风险 | 中 |
| 前端联动成本 | 高 |
| 转发链路风险 | 中高 |
| 是否建议做 | 建议做 |
| 是否适合一次性全量重构 | 可以,但必须有测试和联调环境 |
最终建议
方案 B 是正确方向,尤其解决了当前这几个长期隐患:
- Form 参数和 Query/Header 混用。
- 下游
InParameterList语义不清。 - Json Body 和 Form Mapping Body 混用。
$FromBody表达不准确。- 接口级 Fixed 和接口参数配置职责重叠。
建议按全量重构执行,但不要边改边猜。最好先做后端闭环:
DB 字段 → DTO → Save/Get → ForwardContext → ForwardFlow → Tests
等后端测试跑通后,再让前端按方案 B 调整页面。