如何在Smithy中为Car结构体添加条件必填约束?
实现Smithy结构体的条件必填校验需求
先看你给出的原始结构体定义:
struct Car { @required CarName: String BMWSerialNumber: String }
你需要实现的逻辑是:当CarName等于"BMW"时,强制要求BMWSerialNumber不能为空。但Smithy原生选择器仅作用于Shape(结构体、字段这类静态模型元素),无法基于字段值实现动态校验,可通过以下方案解决:
方案1:自定义Trait + 模型验证插件
这是最贴合Smithy模型驱动理念的方式,能在模型校验阶段就拦截不符合要求的定义:
- 定义一个自定义Trait,标记需要条件必填的字段:
$namespace example.validation /// 指定字段在目标字段匹配特定值时必须填写 @trait(selector: "member") structure RequiredWhen { /// 要检查的目标字段名称 target: String /// 目标字段需要匹配的值 value: String }
- 给
BMWSerialNumber字段添加该Trait:
use example.validation#RequiredWhen struct Car { @required CarName: String @RequiredWhen(target: "CarName", value: "BMW") BMWSerialNumber: String }
- 编写Smithy验证插件(支持Java、TypeScript等语言),遍历所有带
@RequiredWhen的字段,检查对应目标字段值是否匹配,若匹配则验证当前字段是否存在。
方案2:服务端业务逻辑校验
如果不想自定义模型Trait,直接在服务端处理请求时添加校验逻辑更简单:
- 接收
Car结构体数据后,先判断CarName是否为"BMW" - 若为
"BMW",则检查BMWSerialNumber是否为空,为空则返回参数错误
方案3:用Union类型重构模型(推荐)
如果允许调整模型结构,用Union拆分不同车型是最优雅的方式,靠静态类型直接约束BMW必须携带序列号:
union Vehicle { BmwCar: BmwCar OtherCar: OtherCar } struct BmwCar { @required CarName: String = "BMW" @required BMWSerialNumber: String } struct OtherCar { @required CarName: String }
这种方式完全不需要动态校验,借助Smithy的类型系统就能保证数据结构的合法性,更符合Smithy的设计思路。
内容的提问来源于stack exchange,提问作者dwh
相关产品推荐
相关产品推荐

