首页 文章

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

提问于
浏览
12

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

  • 12

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

    • Swagger-Editor和Swagger-UI都没有在文档格式中提供任何指示,以显示对象模式中允许 additionalProperties . 所以,即使你正确地使用了 additionalProperties ,它也会显示出来 . 您需要将此详细信息添加到架构 description ,以便用户了解它们可以包含其他字符串属性 .

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

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

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

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

    我们documented this in detail here .

    好消息:通过小调整,我们可以让Helen 's example work correctly. We just need to extract the nested object schema into its own top-level definition. I' ll称之为 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
    
  • 14

    您对 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
    

    哈希映射中的必需键

    要将 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

  • 0

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

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

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

相关问题