如何在 `map` object 中为 属性 名称编写 OpenAPI 3 (Swagger) 规范?

How to write OpenAPI 3 (Swagger) specification for property name in `map` object?

我试图描述的 API 有一个结构,其中根 object 可以包含任意数量的 child object(属性本身objects)。根object中的“键”或属性是childobject的唯一标识符,值是child的其余部分object的数据。

{
  "child1": { ... bunch of stuff ... },
  "child2": { ... bunch of stuff ... },
  ...
}

这可以类似地建模为数组,例如:

[
  { "id": "child1", ... bunch of stuff ... },
  { "id": "child2", ... bunch of stuff ... },
  ...
]

但这既使得识别 属性 的结构在结构上不太清楚,也使得 children 的 ID 之间的唯一性隐含而不是显式,所以我们想使用 object ,或一张地图。

我看过 Model with Map/Dictionary Properties 的 Swagger 文档,但这并不完全适合我的用例。写这样的东西:

"Parent": {
  "additionalProperties": {
    "$ref": "#/components/schemas/Child",
  }

产生这样的东西:

这充分传达了 属性 中值的描述性,但我如何记录 object 中“键”的限制?理想情况下,我想说类似“它不仅仅是任意字符串,它是对应于 child 的 ID”。这有任何支持吗?

你的例子是正确的。


how do I document what the restrictions are for the "key" in the object? Ideally I'd like to say something like "it's not just any arbitrary string, it's the ID that corresponds to the child". Is this supported in any way?

OpenAPI 3.1

OAS 3.1 完全支持 JSON Schema 2020-12,包括 patternProperties。此关键字可让您使用正则表达式定义字典键的格式:

"Parent": {
  "type": "object",
  "patternProperties": {
    "^child\d+$": {
      "$ref": "#/components/schemas/Child"
    }
  },
  "description": "A map of `Child` schemas, where the keys are IDs that correspond to the child"
}

或者,如果 属性 名称由枚举定义,您可以使用 propertyNames 来定义该枚举:

"Parent": {
  "type": "object",
  "propertyNames": {
    "enum": ["foo", "bar"]
  },
  "additionalProperties": {
    "$ref": "#/components/schemas/Child"
  }
}

OpenAPI 3.0 和 2.0

字典键被假定为字符串,但没有办法限制键的contents/format。您可以在架构 description 中口头记录任何限制和细节。添加架构示例可以帮助说明您的 dictionary/map 可能是什么样子。

"Parent": {
  "type": "object",
  "additionalProperties": {
    "$ref": "#/components/schemas/Child"
  },
  "description": "A map of `Child` schemas, where the keys are IDs that correspond to the child",
  "example": {
    "child1": { ... bunch of stuff ... },
    "child2": { ... bunch of stuff ... },
  }

如果已知可能的键名(例如,它们是枚举的一部分),您可以将字典定义为常规对象,将键定义为单独的对象属性:

// Keys can be: key1, key2, key3

"Parent": {
   "type": "object",
   "properties": { 
      "key1": { "$ref": "#/components/schemas/Child" },
      "key2": { "$ref": "#/components/schemas/Child" },
      "key3": { "$ref": "#/components/schemas/Child" }
   }
}

然后您可以添加 "additionalProperties": false 以真正确保只使用那些密钥。