OpenAPI path/query 参数嵌套结构序列化

OpenAPI path/query parameters nested structure serialization

在有关参数序列化的 OpenAPI 文档中,有一个简短的部分介绍了如何序列化具有不同样式的查询、路径、header 和 cookie 参数。这些参数的架构被描述为 OpenAPI 风格的 json 架构,它允许无限嵌套 objects 和数组。我没有在文档中找到任何关于如何处理这些的提及:

https://swagger.io/docs/specification/serialization/

让我们假设为任何参数提供的 JSON 模式如下:

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "object",
      "properties": {
        "bar": "string"
      }
    }
  }
}

意味着它允许 JSON 中的结构,例如:

{
  "foo": {
    "bar": "hello"
  }
}

或嵌套数组的类似概念:

{
  "type": "array",
  "items": {
    "type": "array",
    "items": {
      "type": "string"
    }
  }
}

允许这样的结构(至少在 JSON 中):

[["a"], ["b"]]

我的问题:

  1. 根据 OpenAPI 规范,路径、查询等参数是否允许这样做?
  2. 如果是,是否有关于如何以规范允许的不同样式序列化这些文件的文档?
  3. 如果不是,官方文档中是否提到过?

我问这个是因为我正在开发需要与 OpenAPI 规范兼容的工具,我想知道我在这里可以期待什么参数格式。我完全意识到嵌套巨型 objects 并尝试将它们序列化为 url 并不是最聪明的主意。但是我对 OpenAPI 规范允许的内容很感兴趣。

简短回答:这是未定义的行为。


大多数 OpenAPI serialization styles are based on RFC 6570, which provides guidance 仅适用于:

  • 原始值,
  • 基元数组,
  • 简单的非嵌套对象(具有原始属性)。

对于其他类型的值(嵌套对象、包含数组的对象、嵌套数组、对象数组),行为未定义。


同样,OpenAPI 自己的 deepObject 样式目前 defined 仅适用于简单对象,不适用于数组或嵌套对象。以下是 OpenAPI 规范中的一些相关评论 authors/maintainers:

By the way, is there a reason we couldn't have deepObject work for arrays too? [...]

Darrel: Supporting arrays as you describe was my intent. I was supposed to find some canonical implementation to use as a guideline for the behavior, but didn't get around to it.

Ron: If we end up supporting the exploded array notation, it needs to be clear that the first index is 0 (or 1, or -1, or whatever).

(source)

Ron: when we defined deepObject in the spec, we explicitly chose to not mention what happens when the object has several levels in it, but in our conversations we went with 'not supported'. ​

(source)

存在扩展 deepObject 以支持数组和嵌套结构的现有功能请求:
Support deep objects for query parameters with deepObject style

OpenAPI 规范 3.0/3.1 支持 JSON 格式的参数序列化。它刚刚在您提到的页面末尾提到。

来自OpenAPI spec 3.0.3

For more complex scenarios, the content property can define the media type and schema of the parameter. A parameter MUST contain either a schema property, or a content property, but not both.

下面的 OpenAPI 片段显示了如何定义问题中具有所需结构的查询参数:

  parameters:
    - name: objParam
      in: query
      content:
        application/json:
          schema:
            type: object
            properties:
              foo:
                type: object
                properties:
                  bar:
                    type: string
    - name: nestedArray
      in: query
      content:
        application/json:
          schema:
            type: array
            items:
              type: array
              items:
                type: string