具有动态键值哈希映射的 Swagger 复杂响应模型

Swagger complex response model with dynamic key value hash maps

我正在努力使用 swagger 的语法来描述响应类型。我要建模的是一个带有动态键和值的哈希映射。这是允许本地化所必需的。语言可能不同,但应始终提供英语。

JSON 中的响应如下所示:

{
  id: "1234",
  name: {
    en: "english text",
    de: "Deutscher Text"
  }
}

我的第一次尝试是这样的,但我不知道如何写名字部分。 AdditionalProperties 似乎是一个关键,但我无法理解它。此外,在这种语法中,对英文文本的要求对我来说是个谜,而且这个例子似乎也没有按预期工作。它在 UI.

中生成一个空的 $folded:
delayReason:
  type: object
  properties:
    id:
      type: string
      description: Identifier for a delay reason.
    name:
      type: object
      additionalProperties: 
        type: string
  required: [id, name]
  example:
    id: 123
    name: 
      en: english text
      de: Deutscher Text

但这会产生:

这里也没有线索,结果将以语言代码作为键,将文本作为散列映射的值。

您对 additionalProperties 的用法是正确的,您的模型也是正确的。

其他属性

在Swagger/OpenAPI中,假设hashmap键是字符串,所以没有明确定义键类型。 additionalProperties 定义 hashmap 值的类型。所以,这个模式

type: object
additionalProperties: 
  type: string

定义一个字符串到字符串的映射,例如:

{
  "en": "English text",
  "de": "Deutscher Text"
}

如果您需要字符串到整数的映射,例如:

{
  "en": 5,
  "de": 3
}

您可以将 additionalProperties 定义为值类型 integer:

type: object
additionalProperties: 
  type: integer

哈希映射中的必需键

要将 en 定义为哈希图中的必需键:

type: object
properties:
  en:
    type: string
required: [en]
additionalProperties: 
  type: string

完整示例

definitions:
  delayReason:
    type: object
    properties:
      id:
        type: string
        description: Identifier for a delay reason.
      name:
        type: object
        description: A hashmap with language code as a key and the text as the value.
        properties:
          en:
            type: string
            description: English text of a delay reason.
        required: [en]
        additionalProperties: 
          type: string
    required: [id, name]
    example:
      id: '123' # Note the quotes to force the value as a string
      name: 
        en: English text
        de: Deutscher Text

There is also no clue in this that the result will have a language code as a key and the text as the value of the hash map.

类似的事情可以在 description 中口头记录。

the example also does not seem to work as expected. It generates an empty $folded: in the UI.

不确定您的原始规范有什么问题,但上面的规范有效并且在 Swagger Editor.

中看起来不错

您似乎 运行 陷入至少三个独立的错误 and/or 局限性:

  1. Swagger-Editor 和 Swagger-UI 都没有在文档格式中提供任何指示来表明 additionalProperties 在您的对象架构中是允许的。因此,即使您正确使用了 additionalProperties,并且它被 Swagger 解析器识别,这些文档格式也不会显示它。您需要将此详细信息添加到您的架构 description,以便用户了解他们可以包含其他字符串属性。

    注意:您可能还希望其他 属性 名称遵循约定,例如两个字母的语言代码。虽然完整的 JSON 模式允许您使用 patternProperties 指定它,但不幸的是,Swagger 的模式对象不支持它。同样,您应该在架构描述中指定它。

  2. Swagger-Editor 格式有时会显示这种奇怪的 "folded:" 属性。我今天早上看到了,奇怪的是现在我无法重现它。今天可能已经修复了。但无论如何,这肯定是一个错误,并且特定于 Swagger-Editor。它不应影响您的下游代码生成,也不应影响在运行时向客户端开发人员提供 API 文档的标准 Swagger-UI。 (虽然 Swagger-Editor 中的文档窗格看起来类似于 Swagger-UI,但它是一个单独的实现。)

  3. 在 Swagger 中使用 additionalProperties 有一些微妙但重要的限制。虽然 Helen 的示例没有显示任何可见的错误,但实际上 Swagger 解析器将无法正确处理此模式;它会忽略您明确声明的 en 属性,或者忽略 additionalProperties

最后一个问题归结为 Swagger-Model 中的设计缺陷,Swagger-Model 是整个 Swagger Java 堆栈(包括 Swagger-Codegen)中使用的核心组件之一。在某些上下文中定义的模式可以与 propertiesadditionalProperties 的组合一起使用。但是在其他上下文中定义的模式不能。

我们 documented this in detail here.

好消息:稍加调整,我们就可以让 Helen 的示例正常运行。我们只需要将嵌套对象模式提取到它自己的顶级定义中。我将其命名为 LocalizedName:

definitions:
  delayReason:
    type: object
    properties:
      id:
        type: string
        description: Identifier for a delay reason.
      name:
        $ref: "#/definitions/LocalizedName"
    required: [id, name]
    example:
      id: '123' # Note the quotes to force the value as a string
      name: 
        en: English text
        de: Deutscher Text

  LocalizedName:
    type: object
    description: A hashmap with language code as a key and the text as the value.
    properties:
      en:
        type: string
        description: English text of a delay reason.
    required: [en]
    additionalProperties: 
      type: string

如果您仍处于设计阶段,而不是使用动态键,您可以将所有其他语言引用推送到一个结构如下的数组中:

{
"launguage":"en"
"text":"Hello World"
}

这会大大简化事情,而且由于您不依赖 additionalProperties,您生成的客户端库会发现这更容易理解。