feat: release nullable mappings and split mapping configuration
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# 公共字段、结构映射与生成选项
|
||||
|
||||
本页对应 `v0.17.0-preview`。CLI 与框架依赖固定到同一版本:
|
||||
本页对应 `v0.18.0-preview`。CLI 与框架依赖固定到同一版本:
|
||||
|
||||
```sh
|
||||
go install git.yuntuo.hk/k2safe/go-omni/cmd/go-omni@v0.17.0-preview
|
||||
go install git.yuntuo.hk/k2safe/go-omni/cmd/go-omni@v0.18.0-preview
|
||||
# 已有业务项目内执行:
|
||||
go get git.yuntuo.hk/k2safe/go-omni@v0.17.0-preview
|
||||
go get git.yuntuo.hk/k2safe/go-omni@v0.18.0-preview
|
||||
```
|
||||
|
||||
私有仓库访问设置见 [安装说明](README.md#准备环境与安装)。升级不会覆盖业务文件;已有中间件保持 handlers 模式,切换工厂模式按本页迁移步骤完成。
|
||||
@@ -28,6 +28,26 @@ go get git.yuntuo.hk/k2safe/go-omni@v0.17.0-preview
|
||||
- `mappings` 可省略;只有明确列出的类型对才生成映射。未启用时不会运行 Go 类型加载命令,也不增加运行时依赖。
|
||||
- 升级首次遇到没有配置的旧 manifest 时,补一份 `middleware: handlers` 的配置,保留原有手写注册;Repository 默认 none。生成配置建立后不能直接删除,否则生成失败,避免误关闭映射或改变中间件模式。
|
||||
|
||||
### 按模块拆分映射(v0.18 新增)
|
||||
|
||||
主配置可以保留少量内联 `mappings`,也可以只列出文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"repository": "none",
|
||||
"middleware": "factories",
|
||||
"mappingFiles": ["mappings/requests.json", "mappings/responses.json"]
|
||||
}
|
||||
```
|
||||
|
||||
每个子文件只包含 `{"mappings": [...]}`,其中每条映射的写法与原来一致。先加载主配置内联定义,再按文件列表顺序加载;所有定义合并后统一校验,可以跨文件、向前引用 `mapping`。输出按映射名排序,文件拆分不改变函数名或语义。
|
||||
|
||||
- 路径相对项目根目录,必须是明确列出的 `.json` 文件。不展开通配符,不允许越界路径、符号链接、重复文件或多层导入;子文件不能覆盖 repository/middleware 等项目选项。
|
||||
- 重名映射、指针辅助函数名冲突、未知映射与循环引用明确报错;文件之间不能用覆盖顺序隐藏冲突。重复定义会指出两个来源文件,字段生成错误也带来源文件。
|
||||
- 文件均由项目维护,重新生成不改写它们。原来的单文件 `mappings` 继续有效。迁移时将完整条目移到子文件并删除原位置,不能复制后保留两份同名定义。
|
||||
- 最多 64 个子文件、单文件 1 MiB、全部配置 4 MiB;合计仍最多 128 个映射。主配置和子文件一起提交 Git。
|
||||
- `api generate`、`--check`、`--dry-run` 与 `workspace generate/check` 使用同一加载逻辑。缺少子文件或不完整配置立即失败,check/预览不写入;生成期间重新核对所有配置输入,发生变化时要求重试。
|
||||
|
||||
## 公共字段组合
|
||||
|
||||
```text
|
||||
@@ -141,6 +161,53 @@ func SalaryValue(source *amount.Money) (amount.Money, error)
|
||||
|
||||
映射不保存原 JSON 的字段存在信息。普通 `*T` 在绑定后可能已把缺失和 null 合并为 nil;无法在转换阶段恢复区分。有三态需要的项目必须先使用能携带该信息的输入类型及绑定扩展;没有声明三态时,保持当前输入类型的语义。完整表单更新和局部更新由业务决定,框架不把 nil 自动解释成“保留旧值”。
|
||||
|
||||
### 可空嵌套映射与显式 nil 策略(v0.18 新增)
|
||||
|
||||
假设已有 `ToChild` 定义 `types.Child → domain.Child`。父对象的字段规则可以直接复用它:
|
||||
|
||||
```json
|
||||
"fields": {
|
||||
"Child": {"source": "Child", "mapping": "ToChild"},
|
||||
"Children": {"source": "Children", "mapping": "ToChild", "elements": true}
|
||||
}
|
||||
```
|
||||
|
||||
| 源字段 → 目标字段 | 明确选择 mapping 后的行为 |
|
||||
| --- | --- |
|
||||
| `S → T` | 调用原值映射 |
|
||||
| `*S → *T` | 默认保留 nil;非 nil 调用值映射,并分配新的目标对象;也可配置 `nil: "error"` 拒绝 nil |
|
||||
| `S → *T` | 调用值映射,成功后返回目标对象指针 |
|
||||
| `*S → T` | 必须选择 `nil: "zero"` 或 `nil: "error"`,不猜默认值 |
|
||||
|
||||
`nil: "preserve"` 只适用于可空源和可空目标。`nil: "zero"` 只适用于可空源和非空目标:nil 直接产生目标 Go 零值,**不调用子映射或转换函数**。`nil: "error"` 在 nil 时返回带映射/字段路径的普通转换错误,HTTP 公开响应仍由项目的错误处理策略决定;需要领域错误码时使用项目 converter。
|
||||
|
||||
同一规则适用于显式 `elements: true` 下的 slice/等长数组元素,包括 `[]*S → []*T`。nil slice、非 nil 空 slice、nil 元素分别保留;元素失败保留索引与内部错误链,整个映射返回零目标值,不交付部分结果。只支持这里列出的单层指针,不自动处理多层指针或递归对象图。
|
||||
|
||||
普通同类型指针字段未指定 mapping 时仍直接赋值、共享引用;上述显式映射会创建目标子对象,但不承诺对其中所有引用深拷贝。业务不可变快照继续由项目设计。
|
||||
|
||||
简单的 `*T → T` 也可以单独指定 nil 策略,减少重复解引用函数:
|
||||
|
||||
```json
|
||||
"fields": {
|
||||
"Title": {"source": "Title", "nil": "zero"},
|
||||
"Count": {"source": "Count", "nil": "error"}
|
||||
}
|
||||
```
|
||||
|
||||
这里必须是完全相同的 Go 元素类型,`*int32 → int64`、枚举 → string、数字编号 → string 仍需显式 converter。非 nil 的零值正常保留。`convert` 与 `nil` 不能同时设置,现有 converter 继续完整控制自己的空值、格式和错误语义。
|
||||
|
||||
### 可选指针返回辅助(v0.18 新增)
|
||||
|
||||
在映射条目上增加 `"pointerResult": true`,生成器保留 `ToResponse(source S) (T, error)`,另加:
|
||||
|
||||
```go
|
||||
func ToResponsePtr(source S) (*T, error)
|
||||
```
|
||||
|
||||
Logic 在业务调用成功后可直接写 `return mapping.ToResponsePtr(result)`。转换失败时返回 `nil, err`,错误链不变;成功才返回非 nil 指针。业务调用本身的错误仍由 Logic 处理,辅助函数不执行任何业务操作。
|
||||
|
||||
辅助函数名称固定为映射名加 `Ptr`,与其他映射/辅助函数同名会在生成前报错。输入仍是原来的值类型 S,不用 nil 输入表达业务错误;关闭该选项会移除辅助函数,使用它的业务代码需同时调整。
|
||||
|
||||
### 生成顺序与 CI
|
||||
|
||||
1. 先从 `.api` 生成项目,添加业务结构、scalar 和转换函数,执行 `go mod tidy`。
|
||||
|
||||
Reference in New Issue
Block a user