如何在OpenAPI规范中定义JSON:API风格的集合查询过滤参数?
解决JSON:API过滤参数在OpenAPI中的定义问题
针对JSON:API规范中filter[attribute][operation]格式的嵌套过滤参数,在OpenAPI里有几种实用的定义方案,以下是具体实现和最佳实践:
方案1:使用deepObject风格(OpenAPI 3.0+推荐)
OpenAPI 3.0及以上支持style: deepObject,可以自动将嵌套的查询参数映射为对象结构,完美适配JSON:API的过滤格式。
示例定义(YAML):
parameters: - name: filter in: query style: deepObject explode: true schema: type: object # 允许任意属性路径(如kind、organisation.id) additionalProperties: type: object # 限定支持的操作类型 properties: eq: type: string description: 精确匹配 in: type: string description: 多值匹配,逗号分隔 "any-like": type: string description: 模糊匹配,支持通配符,多值逗号分隔 between: type: string description: 范围匹配,两个值用逗号分隔(如min,max) additionalProperties: false # 禁止未定义的操作
这样定义后,filter[kind][in]=bot,agent这类参数会被正确解析为filter.kind.in,同时OpenAPI文档会清晰展示支持的操作类型。
方案2:明确指定允许的属性路径(适合属性固定的场景)
如果你的API只允许特定的属性路径进行过滤,可以在schema中明确列出,提升文档的准确性和可读性:
parameters: - name: filter in: query style: deepObject explode: true schema: type: object properties: kind: type: object properties: in: type: string description: 匹配指定的类型列表(如bot,agent) eq: type: string "organisation.id": type: object properties: eq: type: string format: uuid description: 匹配指定的组织ID "customer.phones": type: object properties: "any-like": type: string description: 匹配包含指定前缀的电话号码(如%2b88600000000)
方案3:兼容OpenAPI 2.0的逐个参数定义(不推荐)
如果必须兼容OpenAPI 2.0(不支持deepObject),只能逐个定义每个可能的过滤参数,虽然繁琐但可行:
parameters: - in: query name: filter[kind][in] type: string description: 匹配指定的类型列表 - in: query name: filter[organisation.id][eq] type: string format: uuid description: 匹配指定的组织ID - in: query name: filter[customer.phones][any-like] type: string description: 匹配包含指定前缀的电话号码
最佳实践
- 统一分页参数的定义:分页参数也可以用deepObject风格,和过滤参数保持一致:
parameters: - name: page in: query style: deepObject explode: true schema: type: object properties: limit: type: integer minimum: 1 maximum: 100 default: 10 offset: type: integer minimum: 0 default: 0 - 添加详细描述:为每个操作和属性路径添加清晰的描述,帮助API使用者正确构造请求。
- 严格约束schema:如果有明确的属性或操作限制,尽量在schema中定义,避免非法请求。
内容的提问来源于stack exchange,提问作者Daryl O Regan
相关产品推荐
相关产品推荐

