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

时间:2016-12-12 09:41:37

标签: hashmap swagger swagger-2.0 swagger-editor

我正在努力用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

但这会产生: swagger editor result

此处也没有任何线索,结果将语言代码作为键,文本作为哈希映射的值。

3 个答案:

答案 0 :(得分:15)

您对additionalProperties的使用是正确的,而且您的模型是正确的。

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

hashmap中的必需键

en定义为hashmap中的必需键:

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
  

此处也没有任何线索,结果将语言代码作为键,文本作为哈希映射的值。

这样的事情可以在description中口头记录。

  

该示例似乎也没有按预期工作。它会在UI中生成一个空的$ folded:

不确定原始规格有什么问题,但上面的规范有效且在Swagger Editor中看起来很好。

Model schema in Swagger Editor

答案 1 :(得分:12)

您似乎遇到了至少三个单独的错误和/或限制:

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

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

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

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

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

    我们documented this in detail here

    好消息:通过小调整,我们可以让海伦的榜样正常运作。我们只需要将嵌套对象模式提取到它自己的顶级定义中。我称之为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
    

答案 2 :(得分:0)

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

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

这会简化很多事情,因为你不依赖于additionalProperties,所以你生成的客户端库会发现这更容易消化。