MuleSoft:如何在RAML规范文件中编写choice选择结构
RAML规范中choice选择结构的实操编写方法
很多开发在MuleSoft项目里写RAML时,会误以为RAML有专门的choice关键字,实际上RAML本身没有内置的专属选择结构语法,大家常说的choice能力,是依托RAML兼容的JSON Schema组合校验能力实现的,核心效果是:同个接口入参/返回值的节点,支持配置多套可选的报文结构规则,只要报文命中任意一个合法分支的规则,就算通过结构校验。
两类常见选择结构的实现方式
根据业务场景的校验严格度不同,选择结构的写法分两种:
- 严格互斥的单选分支(
oneOf):要求传入/返回的报文必须且只能命中某一个分支的结构规则,一旦同时符合多个分支规则,就会触发校验失败,适合两个分支结构完全独立、不可能同时出现的业务场景(比如订单的发货报文、退款报文) - 非互斥的兼容分支(
anyOf):要求传入/返回的报文只要命中任意一个分支的结构规则就算校验通过,不限制命中的分支数量,适合同一个字段有多种合法类型/取值规则的场景(比如用户ID既可以是带前缀的字符串,也可以是纯数字)
具体编写代码示例
场景1:严格互斥的报文分支选择(oneOf)
这是最常用的choice场景,比如定义订单回调接口的业务报文,要求根据订单状态不同,要么传发货信息、要么传退款信息,两个分支不能同时存在:
#%RAML 1.0 title: 订单状态回调API version: v1 mediaType: application/json /order/callback: post: body: application/json: type: object: properties: requestId: type: string description: 接口幂等标识 # 此处嵌入choice选择结构 bizPayload: oneOf: - type: object: properties: orderNo: type: string description: 订单编号 shipTime: type: datetime description: 发货时间 logisticsNo: type: string description: 物流单号 required: [orderNo, shipTime, logisticsNo] description: 分支1:订单已发货的回调报文结构 - type: object: properties: orderNo: type: string description: 订单编号 refundAmount: type: number description: 退款金额 refundReason: type: string description: 退款原因 required: [orderNo, refundAmount, refundReason] description: 分支2: 订单已退款的回调报文结构
场景2:多类型兼容的字段选择(anyOf)
比如定义用户ID字段,既支持8位纯数字格式的老用户ID,也支持带U前缀的8位字符串格式的新用户ID,不需要严格限制必须符合某一种格式,就可以用anyOf实现:
type: object: properties: userId: anyOf: - type: number minimum: 10000000 maximum: 99999999 description: 老用户纯数字ID - type: string pattern: "^U[0-9]{8}$" description: 新用户带前缀的字符串ID required: true
编写时的避坑提示
- 不要混用
oneOf和anyOf:如果业务要求结构严格互斥,用anyOf会导致校验规则被放宽,出现本该报错的报文通过校验的问题 - 尽量把多个分支共有的公共字段抽到选择结构的外层定义,减少重复代码,比如上面两个订单分支都需要的
orderNo字段,就可以从子分支抽出来,放到bizPayload的公共属性里定义,每个分支只保留独有的字段 - 对接MuleSoft APIKit时,要确保使用的RAML版本不低于1.0,旧版本的解析器对组合类型的支持存在兼容问题,可能出现结构定义不被识别的情况
- 每个选择分支要补充清晰的描述文本,方便接口对接方快速判断自己需要传哪个分支的报文,减少联调沟通成本
内容的提问来源于stack exchange,提问作者user15592843
相关产品推荐
相关产品推荐

