【问题标题】:Swagger: map of <string, Object>Swagger: <string, Object> 的映射
【发布时间】:2016-07-08 07:22:01
【问题描述】:

我需要使用 Swagger 记录一个 API,该 API 使用对象映射作为输入和输出,由字符串键索引。

例子:

{
    "a_property": {
        "foo": {
            "property_1": "a string 1",
            "property_2": "a string 2"
        },
        "bar": {
            "property_1": "a string 3",
            "property_2": "a string 4"
        }
    }
}

"foo" 和 "bar" 可以是任何字符串键,但它们在键集中应该是唯一的。

我知道,使用 Swagger,我可以定义一个对象数组,但这提供了不同的 API,因为我们将拥有如下内容:

{
    "a_property": [
        {
            "key": "foo"
            "property_1": "a string 1",
            "property_2": "a string 2"
        },
        {
            "key": "bar"
            "property_1": "a string 3",
            "property_2": "a string 4"
        }
    ]
}

我已阅读'Open API Specification' - 'Add support for Map data types #38' 页面。据我了解,它建议使用 additionalProperties,但它似乎无法满足我的需求(或者它不适用于我使用的 Swagger UI 2.1.4)。 我错过了什么吗?

到目前为止,我已经找到了以下解决方法(在 Swagger JSON 中):

a_property: {
    description: "This is a map that can contain several objects indexed by different keys.",
    type: object,
    properties: {
        key: {
            description: "map item",
            type: "object",
            properties: {
                property_1: {
                    description: "first property",
                    type: string
                },
                property_2: {
                    description: "second property",
                    type: string
                }
            }
        }
    }
}

这几乎可以完成这项工作,但读者必须了解“key”可以是任何字符串,并且可以重复多次。

有没有更好的方法来实现我的需要?

【问题讨论】:

标签: dictionary swagger openapi


【解决方案1】:

使用 additionalProperties 是使用 OpenAPI (fka. Swagger) 规范描述 hashmap 的正确方法,但 Swagger UI 目前不呈现它们。

在此处跟踪问题https://github.com/swagger-api/swagger-ui/issues/1248

同时你可以使用这个技巧:定义地图对象的相同类型的非必需属性(在下面的示例中为default)并在描述中给出一些提示:

swagger: "2.0"
info:
  version: 1.0.0
  title: Hashmap
  
paths: {}

definitions:
  MapItem:
    properties:
      firstname:
        type: string
      lastname:
        type: string
  Map:
    description: a (key, MapItem) map. `default`is an example key
    properties:
      default:
        $ref: '#/definitions/MapItem'
    additionalProperties:
      $ref: '#/definitions/MapItem'

此描述不会修改 API 合约并改进文档。

【讨论】:

  • 感谢您在 SwaggerUI 中找到相关问题的参考。不幸的是,我还没有足够的声誉来投票给你的答案;-)
  • 截至目前,至少 swagger-codegen 的 javascript 版本忽略了其他属性,因此对于某些人来说它可能是一个炫耀
  • 其他属性不会这样做。其他属性无法解决我的值可以具有特定架构的事实
  • 很好的答案,但仍不清楚如何将string 定义为键类型(如果$ref 作为键)。 swagger.io/docs/specification/data-models/dictionaries 也不清楚。
【解决方案2】:

如果我理解正确,基本问题是 Java Map 没有普遍接受的 JSON 映射,尤其是当键比字符串更复杂时。我已经看到 GSON 采用一种方法(将密钥视为对象),而 Jackson 采用另一种方法(将密钥序列化为字符串)。等效于 Map(字典)的 c# 使用第三种方法(将每个条目视为其自身的键值对象,具有称为“键”和“值”的属性)。 由于 Swagger 试图与语言和序列化器无关,这使其处于不可能的位置。

【讨论】:

    【解决方案3】:

    您可以简单地将类型用作对象。当我们从前端解析数据时,我们没有 Map 这样的东西。我们只是发送对象。地图取决于后端的东西。这就是为什么我要求使用 object 作为类型。在对象中,我们可以发送键值对。如下例所示

      metaData:
        type: object
        example: {
          "heading":"comfirmation email"
        }
    

    【讨论】:

    • 你能澄清你的意思吗?事实上,这并不完全清楚。这一点在这里尤其重要,因为有一个得到社区广泛验证的答案,获得了 50 票。
    • @JeremyCaney 映射意味着它是一组键值对。我们没有从前端传递 Map 之类的东西。取而代之的是,我们正在从前端解析一个对象。这就是为什么我要求在其中使用 object 作为数据类型。这是我用过的一个例子metaData: type: object example: { "heading":"comfirmation email" }
    • 这很有帮助!我可以建议edit你的答案包括那个细节吗?
    • 请添加您的评论建议以改进答案。
    • @JeremyCaney 是的,你可以编辑
    【解决方案4】:

    通过使用additionalProperties

    definitions:
      String-StringStringMap: # <-- use this as your result
        type: object
        additionalProperties:
          $ref: "#/definitions/StringStringMap"
    
      StringStringMap:
          type: object
          additionalProperties:
            type: string
    

    这会产生一个 2 级地图:

    {
      "additionalProp1": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      },
      "additionalProp2": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      },
      "additionalProp3": {
        "additionalProp1": "string",
        "additionalProp2": "string",
        "additionalProp3": "string"
      }
    }
    

    同样的想法,你也可以指定一个 3 级地图。

    【讨论】:

      猜你喜欢
      • 2012-12-20
      • 2017-11-25
      • 2011-06-17
      • 1970-01-01
      • 2011-01-29
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多