Swagger:<string,Object>的地图

Xav*_*tte 20 dictionary swagger

我需要用Swagger记录一个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"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

"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"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了"开放API规范" - "添加对地图数据类型#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
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这几乎完成了这项工作,但读者必须明白"key"可以是任何字符串,并且可以重复多次.

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

Arn*_*ret 36

使用additionalProperties是使用OpenAPI(fka.Swagger)规范描述hashamp的正确方法,但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'
Run Code Online (Sandbox Code Playgroud)

此描述不会修改API合同并改进文档.


Dan*_*ári 10

通过使用additionalProperties

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

  StringStringMap:
      type: object
      additionalProperties:
        type: string
Run Code Online (Sandbox Code Playgroud)

这会产生一个 2 级地图:

{
  "additionalProp1": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  },
  "additionalProp2": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  },
  "additionalProp3": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}
Run Code Online (Sandbox Code Playgroud)

出于同样的想法,您也可以指定 3 级地图。


小智 6

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