我需要使用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”可以是任何字符串,并且可以重复几次。
有没有更好的方法来实现我的需求?
答案 0 :(得分:31)
使用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'
此说明不会修改API合同并改进文档。
答案 1 :(得分:3)
如果我理解正确,基本问题是Java Map没有普遍接受的JSON映射,特别是当密钥比字符串更复杂时。我已经看到GSON采用一种方法(将密钥视为对象),而Jackson采用另一种方法(将密钥序列化为字符串)。与Map(字典)等效的c#使用第三种方法(将每个条目作为键值对象单独处理,其属性称为“Key”和“Value”)。 由于Swagger试图与语言和序列化器无关,这使它处于一个不可能的位置。