itfx/方案B-重构清单-前后对比.md
2026-06-03 14:49:58 +08:00

373 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 方案 B 重构清单(前后对比 · 修订版)
> **前提**:全量重构,不做旧字段兼容。
> **修订要点**:先定义「一次 HTTP 请求」应保存哪些结构,再说明 **Mapping Body 仅在某些 Content-Type 下才存在**`application/json` 的请求体参数树 **本身就是映射体**,不单独拆 Mapping Body。
---
## 1. 设计顺序(先看这个)
```text
第一步 请求接口应保存什么(与 Content-Type 无关 + 有关部分分开)
Query / Header / Body 传输层 + 响应 + 基本信息
第二步 映射体放哪(由 Content-Type 决定)
Json/Xml → Body 参数树 = 映射体
Form 类 → 传输用表单 KV + 独立 Mapping Body 树(表单字段可 $FromMappingBody
```
**Mapping Body 不是每个接口都有**只有「Body或 Query走表单 KV且业务 JSON 需要单独做上游映射」时才配置。
---
## 2. 改造后:一次请求应保存什么(目标模型)
### 2.1 与 Content-Type **无关**(任何下游接口都有)
| 存储 | 表 | UI对齐 ApiTest | 说明 |
|------|-----|-------------------|------|
| **基本信息** | `t_interface` | 地址、Method、Protocol、ContentType、QPS… | 不变 |
| **Query** | `t_parameter_form`FieldPosition=**Query** | Query TabKV | 真实 URL Query不仅 FormUrlEncoded 才有 |
| **Header** | `t_parameter_form`FieldPosition=**Header** | Header TabKV | 请求头;占位符 $TimeStamp、$token 等 |
| **Response** | `t_parameter`IsInPara=false | Response 参数树 | 不变 |
| **返回配置** | `t_interface_return_config` | 返回配置 Tab | 不变 |
| **cURL 示例** | `t_interface.InParams` | cURL Tab | 不变 |
| **服务商级 Fixed** | `t_parameter_fixed`ServiceProviderId | 不在接口明细维护 | Url 占位、服务商通用 Header、脚本写入 |
### 2.2 与 Content-Type **有关**Body 区不同)
| ContentType | Body 传输层保存什么 | 映射体保存什么 | 是否需要 Mapping Body |
|-------------|---------------------|----------------|------------------------|
| **Json (3)** | **`requestBodyParameterList`** 参数树 | **同一棵树** | **否** |
| **Xml (4)** | **`requestBodyParameterList`** 参数树 | **同一棵树** | **否** |
| **FormUrlEncoded (1)** | **`bodyFormParameterList`** KV | **`mappingBodyParameterList`** 参数树 | **是** |
| **FormData (2)** | 二期:`bodyForm` 或 multipart 描述 | 若字段内嵌 JSON同 FormUrlEncoded | 二期 |
| **上游接口** | **`inParameterList`** 树(业务入参) | **同一棵树** | **否** |
### 2.3 结构总图(改造后)
```text
┌─ 基本信息 (t_interface)
任意 Content-Type ├─ queryFormParameterList (t_parameter_form, Query)
├─ headerFormParameterList (t_parameter_form, Header)
├─ Body 区 ─────────────────────────────────────┐
│ │
│ Json/Xml FormUrlEncoded │
│ requestBody bodyFormParameterList │
│ ParameterList (KV 传输) │
│ (树=映射体) mappingBodyParameterList │
│ (树=仅映射体) │
└────────────────────────────────────────────────┘
├─ outParameterList (出参树)
└─ inParams (cURL 示例)
```
### 2.4 页面 Tab下游接口 · 按 Content-Type 显示)
| Tab | Json / Xml | FormUrlEncoded |
|-----|------------|----------------|
| Query | 显示 KV | 显示 KV |
| Header | 显示 KV | 显示 KV |
| **Body** | **参数树**= 映射体) | **KV 表**(传输) |
| **Mapping Body** | **隐藏** | **显示**(参数树) |
| cURL | 显示 | 显示 |
| Response | 显示 | 显示 |
| ~~固定配置~~ | 删除(接口级) | 删除 |
与 ApiTest 对齐方式:
- ApiTest 的 Request TabJson 时常用 Raw**接口配置**里 Json 仍用 **参数树** 定义结构itfx 现有能力,且即映射体)。
- ApiTest 的 FormUrlEncodedURL Encoded KV = 我们的 **bodyForm**;映射结构不在调试页里,在接口配置里用 **Mapping Body** 维护。
---
## 3. Mapping Body 何时存在(规则定稿)
| 条件 | 结论 |
|------|------|
| `ContentType = Json``Xml` | **没有** `mappingBodyParameterList``requestBodyParameterList` 参与 `InParamRestructure` 且被 `SerializationBody` 序列化 |
| `ContentType = FormUrlEncoded` | **有** `bodyFormParameterList` + **有** `mappingBodyParameterList`;映射只对 Mapping Body 树;表单字段值可为 `$FromMappingBody` |
| Query 上也有「值为 JSON」的罕见情况 | 仍用 Mapping Body 树做映射Query KV 里字段填 `$FromMappingBody`(与 Body 表单同理) |
| 上游 `IsUpStream=true` | 始终只有 **`inParameterList`**,无 Mapping Body、无 bodyForm |
**占位符**
| 占位符 | 用于 | Content-Type |
|--------|------|----------------|
| `$FromMappingBody` | Form 的 Query/Body及必要时 Header字段引用映射结果 | **仅 Form 类** |
| `$FromBody` | **删除**下游表单中的用法 | — |
| Json Body 树字段 | 直接映射到 alias**不需要**占位符塞整段 JSON | Json / Xml |
---
## 4. 数据库(修订)
### 4.1 `t_parameter_form` — 传输层 KV
**新增** `FieldPosition`Header=1, Body=2, Query=3。
| FieldPosition | 何时有数据 |
|---------------|------------|
| Query | 任意 Content-Type有 URL 参数就配 |
| Header | 任意 Content-Type |
| Body | **主要 FormUrlEncoded**Json/Xml 通常 **无 body 行**Body 在参数树) |
### 4.2 `t_parameter` — 参数树
**新增** `ParaKind`
| ParaKind | 含义 | 用于 |
|----------|------|------|
| **0 Normal** | 默认 | 出参;**上游入参**Json/Xml 的 **RequestBody** |
| **1 MappingBody** | 仅映射、不直接当 HTTP Json Body | **仅** FormUrlEncoded及日后 FormData且需要独立映射体时 |
| 列表字段 | ParaKind | IsInPara |
|----------|----------|----------|
| `requestBodyParameterList` | Normal或枚举值 RequestBody=0 | true |
| `mappingBodyParameterList` | **MappingBody** | true |
| `outParameterList` | Normal | false |
**删除的用法**
- 不再用「一棵 in 树」同时表示 Form 映射 + Json Body改造前混用
### 4.3 `t_parameter_fixed`
- **删**:接口明细维护接口级 Header/Query/Body KV。
- **留**服务商级、Url、脚本动态 Header。
---
## 5. SaveInterface / GetInterfaceById请求结构
`POST /api/Interface/SaveInterface` · 响应为接口 `id`number
`GetInterfaceById` 字段与保存一致。已删除:`formParameterList`、下游 `inParameterList`
### 5.1 根对象
| 字段 | 说明 |
|------|------|
| `optionType` | `1` 增 / `3` 改 / `2` 删 |
| `isUpStream` | `true` 上游 / `false` 下游 |
| `serviceProviderId` | 上游 `0` |
| `id` | 改、删必填 |
| `name`, `requestAddress`, `requestProtocol`, `requestMethod`, `contentType` | 基本信息 |
| `code`, `category`, `description`, `isBatch`, `limit`, `responseContentType`, `flowCode`, `isDisableAuth`, `qps`, `mappedParamType`, `inParams` | 可选 |
| `queryFormParameterList` | Query KV`fieldPosition=3` |
| `headerFormParameterList` | Header KV`fieldPosition=1` |
| `outParameterList` | 出参树 |
| `requestBodyParameterList` | **仅下游 Json/Xml**Body 树 = 映射体 |
| `bodyFormParameterList` | **仅下游 FormUrlEncoded**Body KV |
| `mappingBodyParameterList` | **仅下游 FormUrlEncoded**,映射树 |
| `inParameterList` | **仅上游**入参树 |
### 5.2 Body 字段互斥
| 场景 | 传 | 不传 |
|------|-----|------|
| 下游 Json/Xml (`contentType` 3/4) | `requestBodyParameterList` | `bodyForm*`、`mappingBody*`、`inParameterList` |
| 下游 FormUrlEncoded (`1`) | `bodyFormParameterList` + `mappingBodyParameterList` | `requestBody*`、`inParameterList` |
| 上游 | `inParameterList` | `requestBody*`、`bodyForm*`、`mappingBody*` |
### 5.3 子结构
**FormParameterInput**Query / Header / Body 行)
```json
{ "optionType": 1, "id": 0, "name": "字段名", "value": "$FromMappingBody", "description": "", "fieldPosition": 2 }
```
`fieldPosition``1` Header · `2` Body · `3` Query。Form 业务 JSON 字段用 `$FromMappingBody`
**ParameterInput**树节点requestBody / mappingBody / in / out
```json
{ "optionType": 1, "id": 1, "pId": 0, "name": "order", "alias": "order", "type": 3, "isRequired": true, "sort": "1", "paraKind": 0 }
```
`paraKind``0` NormalrequestBody、上游 in、出参· `1` MappingBody仅 mappingBody 列表)。新增时 `id`/`pId` 需表达父子关系。
---
## 5.4 示例
**下游 · Json**`contentType: 3`
```json
{
"optionType": 1,
"isUpStream": false,
"serviceProviderId": 5,
"name": "创建订单",
"requestAddress": "https://api.example.com/order",
"requestProtocol": 2,
"requestMethod": 2,
"contentType": 3,
"queryFormParameterList": [
{ "optionType": 1, "id": 0, "name": "access_token", "value": "$FromAccount", "fieldPosition": 3 }
],
"headerFormParameterList": [],
"requestBodyParameterList": [
{ "optionType": 1, "id": 1, "pId": 0, "name": "orderId", "alias": "orderId", "type": 1, "paraKind": 0 }
],
"outParameterList": []
}
```
**下游 · FormUrlEncoded**`contentType: 1`
```json
{
"optionType": 3,
"isUpStream": false,
"serviceProviderId": 5,
"id": 1001,
"name": "1688回调",
"requestAddress": "https://gw.open.1688.com/openapi/http",
"requestProtocol": 2,
"requestMethod": 2,
"contentType": 1,
"queryFormParameterList": [
{ "optionType": 3, "id": 11, "name": "_aop_timestamp", "value": "$TimeStamp", "description": "ms", "fieldPosition": 3 }
],
"headerFormParameterList": [],
"bodyFormParameterList": [
{ "optionType": 3, "id": 10, "name": "notifyBizEventDTO", "value": "$FromMappingBody", "fieldPosition": 2 },
{ "optionType": 3, "id": 13, "name": "_aop_signature", "value": "", "fieldPosition": 2 }
],
"mappingBodyParameterList": [
{ "optionType": 3, "id": 1, "pId": 0, "name": "order", "alias": "order", "type": 3, "paraKind": 1 },
{ "optionType": 3, "id": 2, "pId": 1, "name": "orderId", "alias": "orderId", "type": 1, "paraKind": 1 }
],
"outParameterList": []
}
```
**上游**`isUpStream: true`
```json
{
"optionType": 1,
"isUpStream": true,
"serviceProviderId": 0,
"name": "标准创建订单",
"requestAddress": "/api/order/create",
"requestProtocol": 2,
"requestMethod": 2,
"contentType": 3,
"queryFormParameterList": [],
"headerFormParameterList": [],
"inParameterList": [
{ "optionType": 1, "id": 1, "pId": 0, "name": "order", "alias": "order", "type": 3, "paraKind": 0 }
],
"outParameterList": []
}
```
---
## 6. 转发逻辑(修订)
### 6.1 映射树来源InParamTreeList
| ContentType | InParamTreeList 来源 |
|-------------|----------------------|
| Json / Xml | **`requestBodyParameterList`**(整棵树) |
| FormUrlEncoded | **`mappingBodyParameterList`** |
| 上游 | 系统接口 **inParameterList**(映射配置页不变) |
### 6.2 HTTP 组装
| 部分 | 来源 |
|------|------|
| URL Query | `queryFormParameterList`+ 服务商 Fixed Query |
| Header | `headerFormParameterList`+ 服务商 Fixed Header |
| Body Json | `Serialize(requestBodyParameterList` 映射结果 `)` |
| Body FormUrlEncoded | 仅 **`bodyFormParameterList`**;其中 `$FromMappingBody` ← 映射结果序列化 |
| Body Xml | 同 JsonXml 序列化 |
### 6.3 流程对比(两张)
**Json 下游(无 Mapping Body**
```text
上游 JSON → Restructure(requestBodyParameterList) → OriginalInterfaceMappedInput
→ ReplacePlaceholder(Query/Header form + Fixed)
→ SerializationBody(Json) → HTTP Body
→ 拼 Query / Header
```
**FormUrlEncoded 下游(有 Mapping Body**
```text
上游 JSON → Restructure(mappingBodyParameterList) → OriginalInterfaceMappedInput
→ ReplacePlaceholder含 bodyForm 的 $FromMappingBody
→ bodyForm 字典 → HTTP Body
→ 拼 Query / Header
```
---
## 7. 前后对比总表(增删改)
### 7.1 删除了什么
| 类别 | 内容 |
|------|------|
| API | 下游 `formParameterList`、下游笼统的 `inParameterList`(拆开后互斥) |
| UI | 固定配置 Tab接口级 Fixed API |
| 语义 | 所有下游共用一棵 in 树Form 无 positionJson 也搞 Mapping Body Tab |
| 占位 | 下游表单用 `$FromBody` 表示整段 JSON |
### 7.2 新增了什么
| 类别 | 内容 |
|------|------|
| 表 | `t_parameter_form.FieldPosition``t_parameter.ParaKind` |
| API | `queryFormParameterList`、`headerFormParameterList`**全类型共有** |
| API | `bodyFormParameterList`**仅 Form 类** |
| API | `requestBodyParameterList`**仅 Json/Xml**=映射体) |
| API | `mappingBodyParameterList`**仅 Form 类** |
| UI | Header TabForm 时 Mapping Body TabJson 时 Body=树 |
| 占位 | `$FromMappingBody`**仅 Form KV** |
### 7.3 改了什么
| 项 | 改造前 | 改造后 |
|----|--------|--------|
| Query | 假 Query实为 form body | 真 Query KV**所有 Content-Type** |
| Body Tab | 永远是参数树 | **Json=树****Form=KV** |
| 映射体 | 永远 in 树 | **Json=Body 树****Form=Mapping Body 树** |
| 保存 | form + in 混传 | 按 ContentType 传 **互斥** 的 Body 相关列表 |
| 映射 SQL | 下游 IsInPara 全量 | JsonRequestBody 树Form**ParaKind=MappingBody** |
---
## 8. Content-Type 全量对照(改造后)
| ContentType | queryForm | headerForm | bodyForm | requestBody 树 | mappingBody 树 | 映射目标 | HTTP Body |
|-------------|-----------|------------|----------|----------------|----------------|----------|-----------|
| **Json** | 可选 | 可选 | **不用** | **必填** | **不用** | requestBody 树 | 序列化该树 |
| **Xml** | 可选 | 可选 | **不用** | **必填** | **不用** | requestBody 树 | Xml 序列化 |
| **FormUrlEncoded** | 常用 | 常用 | **必填** | **不用** | **必填** | mappingBody 树 | bodyForm 字典 |
| **FormData** | 二期 | 二期 | 二期 | **不用** | 二期 | 二期 | 二期 |
| **上游 Json** | — | — | — | **inParameterList** | — | in 树 | — |
---
## 9. 一句话
| | 改造前 | 改造后 |
|---|--------|--------|
| 先保存什么 | form + in 混在一起 | **先** Query/Header通用+ **再按 Content-Type 存 Body** |
| Json | in 树 = 映射 + Body | **requestBody 树 = 映射体**,不要 Mapping Body |
| Form | in 树 + form 表 | **bodyForm 传输** + **mappingBody 映射** |
| Mapping Body | (之前文档)每个下游都有 | **仅 Form 类需要** |
---
*文档版本2026-06-02 · 含 SaveInterface 结构与示例§5*