关于hash:为什么`additionalProperties`是在Swagger / OpenAPI 2.0中表示Dictionary / Map的方法

Why `additionalProperties` is the way to represent Dictionary/Map in Swagger/OpenAPI 2.0

虽然我已经看到了OpenAPI规范中的示例:

1
2
3
type: object
additionalProperties:
  $ref: '#/definitions/ComplexModel'

对我来说,为什么使用additionalProperties是Map / Dictionary的正确模式并不明显。

关于additionalProperties的规范唯一具体的事情是,它也无济于事:

The following properties are taken from the JSON Schema definition but their definitions were adjusted to the Swagger Specification. Their definition is the same as the one from JSON Schema, only where the original definition references the JSON Schema definition, the Schema Object definition is used instead.

  • items
  • allOf
  • properties
  • additionalProperties


陈,我觉得你的答案是正确的。

一些可能有用的背景:

在JavaScript中,它是JSON的原始上下文,对象就像字符串到值的哈希映射,其中一些值是数据,其他值是函数。您可以将每个名称 - 值对视为属性。但JavaScript没有类,因此属性名称不是预定义的,每个对象都可以拥有自己独立的属性集。

JSON Schema使用properties关键字来验证事先已知的名称 - 值对;并使用additionalProperties(或patternProperties,OpenAPI 2.0中不支持)来验证未知的属性。

为清楚起见:

  • 地图中的属性名称或"键"必须是字符串。它们不能是数字或任何其他值。
  • 如你所说,属性名称应该是唯一的。不幸的是,JSON规范并不严格要求唯一性,但建议使用唯一性,并且大多数JSON实现都需要这种唯一性。更多背景在这里。
  • propertiesadditionalProperties可以单独使用或组合使用。当单独使用additionalProperties而没有属性时,该对象本质上用作map,其中T是additionalProperties子模式中描述的类型。也许这有助于回答您的原始问题。
  • 在针对单个模式评估对象时,如果属性名称与properties中指定的属性名称匹配,则其值仅需要针对为该属性提供的子模式有效。 additionalProperties子模式(如果提供)仅用于验证properties映射中未包含的属性。
  • 在Swagger的核心Java库中实现了additionalProperties的一些限制。我在这里记录了这些限制。


首先,我找到了additionalProperties的更好解释:

For an object, if this is given, in addition to the properties defined in properties all other property names are allowed. Their values must each match the schema object given here. If this is not given, no other properties than those defined in properties are allowed.

所以这就是我最终如何理解这一点:

使用properties,我们可以定义一组类似于Python的namedtuple的已知属性,但是如果我们希望有更像Python的dict,或者任何其他的hash / map,我们无法指定有多少键,也不知道它们是什么提前,我们应该使用additionalProperties

additionalProperties将匹配任何属性名称(将作为dict的键,$reftype将是dict的值的架构,因为不应该有更多对于每个给定对象,只有一个具有相同名称的属性,我们将获得唯一键的强制执行。

请注意,与Python的dict不同,它接受任何不可变值作为键,因为这里的键本质上是属性名称,它们必须是字符串。 (感谢Ted Epstein的澄清)。可以在json规范中将此限制跟踪到pair := string : value