67 lines
4.2 KiB
Markdown
67 lines
4.2 KiB
Markdown
# Model / Request / Response 组织规范
|
||
|
||
## 适用范围
|
||
|
||
- 判断实体、API 入参、API 出参、`vo` 的落点时,使用本文。
|
||
- 新增或修改 `model/<module>`、`model/<module>/request`、`model/<module>/response` 时,使用本文。
|
||
|
||
## 结论基线
|
||
|
||
- 不建顶层 `vo` 目录;所有数据载体统一归入 `model` 体系。
|
||
- 实体只承载表结构和业务实体字段;禁止承载分页、筛选、排序、展示聚合字段。
|
||
|
||
| 类型 | 固定落点 | 用途 |
|
||
|:---|:---|:---|
|
||
| 实体 | `model/<module>` | GORM 映射、业务实体 |
|
||
| 入参 | `model/<module>/request` | 查询、分页、排序、保存、动作参数 |
|
||
| 出参 | `model/<module>/response` | 详情包装、列表项、聚合字段、展示转换 |
|
||
| 通用结构 | `model/common/request`、`model/common/response` | 跨模块稳定复用 |
|
||
|
||
## 判定规则
|
||
|
||
| 场景 | 结论 |
|
||
|:---|:---|
|
||
| 入参 = 可公开写入的实体字段,且无额外语义 | 可复用实体 |
|
||
| 入参只开放部分字段,或需要屏蔽敏感/系统字段 | 必须使用 `request` |
|
||
| 入参包含分页、筛选、排序、动作语义、组合参数 | 必须使用 `request` |
|
||
| 返回实体原样或实体列表 | 可直接返回实体 |
|
||
| 返回包含展示、聚合、联表、树、嵌套结构 | 必须使用 `response` |
|
||
| 关联表列表/详情需要给前端展示关联对象名称、标题、label | 必须使用 `response` 联表展示字段,实体只保留外键 ID |
|
||
| 多个接口 contract 完全一致 | 复用同一个 `request/response` |
|
||
| `admin/app` 字段、校验、分页、展示口径不同 | 按端拆分 `request/response` |
|
||
|
||
## 强制规则
|
||
|
||
- 新增实体必须放 `model/<module>`;正式 API contract 必须放 `request` 或 `response`。
|
||
- 禁止在 `API` 文件中长期维护正式 contract 的匿名结构体。
|
||
- 新增 `request/response` 前,必须先检查同模块现有结构是否可复用。
|
||
- `request/response` 只有字段、校验语义、返回语义明显不同,才允许新增。
|
||
- 同一业务模块存在 `admin/app` 两套接口时,实体只保留一份;仅 `request/response` 按端拆分。
|
||
- 改实体字段时,必须同步检查 `doc-sql`、`Service` 查询/写入、`API` 绑定/返回。
|
||
- 改 `request/response` 或接口 contract 时,必须同步检查并更新 `doc-api`、`API`、`Service`。
|
||
- 关联表实体只能承载自身字段和外键 ID,禁止把关联对象的 `name/title/label` 等展示字段写入实体或 `doc-sql`。
|
||
- 关联表的 admin 列表响应默认必须补充主要关联对象展示字段,字段名使用 `<关联对象语义><Name/Title/Label>`,例如 `authorName`、`bookTitle`、`typeLabel`。
|
||
- 关联表详情响应如果用于前端详情页、编辑弹窗或审阅页面,也必须返回与列表一致的关联展示字段;纯内部读取接口可只返回实体。
|
||
- 展示字段来源必须由 `Service` 通过 `JOIN`、预加载或批量查询组装到 `response`,禁止要求前端拿到 ID 后再逐条反查名称。
|
||
- 关联展示字段只读;`Create/Update` 请求仍只接收外键 ID 和可编辑业务字段,禁止接收或信任前端传入的展示名称。
|
||
- 若列表支持按关联展示字段搜索或排序,`total` 统计查询必须同步使用等价关联条件,避免分页总数和列表数据不一致。
|
||
|
||
## 推荐做法
|
||
|
||
| 对象 | 模板 | 示例 |
|
||
|:---|:---|:---|
|
||
| 列表查询入参 | `<StructName>Search` | `BookSearch` |
|
||
| 动作入参 | `<Action><StructName>Req` | `ChangePasswordReq` |
|
||
| 详情出参 | `<StructName>Response` | `BookResponse` |
|
||
| 列表项出参 | `<StructName>ListItem` | `BookListItem` |
|
||
| 关联展示字段 | `<Related> + Name/Title/Label` | `authorName`、`bookTitle` |
|
||
| 选项出参 | `<StructName>Option` | `AuthorOption` |
|
||
| 文件 | `model/<module>/<resource>.go`、`model/<module>/request/<resource>.go`、`model/<module>/response/<resource>.go` | `model/book/book.go` |
|
||
|
||
## 禁止事项
|
||
|
||
- 禁止新建顶层 `vo` 目录,与 `model` 并行维护数据结构。
|
||
- 禁止为每个 API 机械复制字段几乎相同的 `request/response`。
|
||
- 禁止把分页、排序、筛选、展示、聚合、临时返回字段塞进实体。
|
||
- 禁止用 `map[string]interface{}`、`gin.H` 作为正式业务出参。
|