为啥 `additionalProperties` 是在 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式

Posted

技术标签:

【中文标题】为啥 `additionalProperties` 是在 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式【英文标题】:Why `additionalProperties` is the way to represent Dictionary/Map in Swagger/OpenAPI 2.0为什么 `additionalProperties` 是在 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式 【发布时间】:2017-05-05 12:39:24 【问题描述】:

虽然我看过OpenAPI spec中的例子:

type: object
additionalProperties:
  $ref: '#/definitions/ComplexModel'

这对我来说并不明显为什么使用additionalProperties 是地图/字典的正确模式。

规范中关于additionalProperties 的唯一具体内容是:

以下属性取自 JSON 架构定义,但它们的定义已根据 Swagger 规范进行了调整。它们的定义与 JSON Schema 的定义相同,只是在原始定义引用 JSON Schema 定义的地方,使用了 Schema Object 定义。

项目 全部 属性 其他属性

【问题讨论】:

【参考方案1】:

陈,我觉得your answer是对的。

一些可能有帮助的进一步背景:

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

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

为了清楚起见:

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

【讨论】:

Epstien,虽然您的回答是正确的,但我不确定它是否解决了我一直在努力解决的问题:additionalProperty 为何将(双关语)映射到字典或地图。此外,如果我的回答大部分正确,那它有些不正确,我从你的回答中不明白其中有什么不正确的地方。 Chen,感谢 cmets。我用更多细节更新了我的答案,希望对您和其他读者有所帮助。我回答的重点是提供一些进一步的背景和见解,而不是纠正您的答案。希望我的第三个要点,结合上下文,回答你原来的问题(虽然不一定比你自己的答案更好)。 Chen,您的回答中只有几点可能不是 100% 正确,我试图在回答中解决这些问题。 (1) 如果您的答案是“键(它们的名称或编号)”,这似乎表明属性可以使用数字值作为键。实际上,名称必须是字符串。 (2) 你说“additionalProperties 将匹配任何属性名称”的地方可能很明显,但我想我应该指出它不会匹配包含在properties 关键字下的属性名称。跨度> 特德,感谢您的评论。当我写“他们的名字或号码”时,我的意思是说“钥匙的名字或有多少钥匙”,我修正了我的答案以避免这种混淆。【参考方案2】:

首先,我找到了better explanation for additionalProperties

对于一个对象,如果给出了这个,除了properties 中定义的属性之外,所有其他属性名称都是允许的。它们的值都必须与此处给出的模式对象相匹配。如果没有给出,则不允许使用除properties 中定义的属性之外的其他属性。

这就是我最终理解的方式:

使用properties,我们可以定义一组类似于Python's namedtuple 的已知属性,但是如果我们希望拥有更像Python's dict 或任何其他我们无法指定多少键的散列/映射事先也没有,我们应该使用additionalProperties

additionalProperties 将匹配任何属性名称(将充当 dict 的键,$reftype 将是 dict 值的模式,因为应该每个给定对象的同名属性不超过一个,我们将强制执行唯一键。

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

【讨论】:

很好的解释 - 希望我早点找到这个!

以上是关于为啥 `additionalProperties` 是在 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式的主要内容,如果未能解决你的问题,请参考以下文章

了解 JSON Schema 草稿版本 4 中的“additionalProperties”关键字

递归 JSON 模式

JSON Schema - 需要所有属性

activiti怎么实现用户自定义流程

pb中如何统一设置数据窗口字体大小

JSON 模式 - 如果对象*不*包含特定属性则有效