为啥 `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。properties
和 additionalProperties
可以单独使用或组合使用。当 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
的键,$ref
或 type
将是 dict
值的模式,因为应该每个给定对象的同名属性不超过一个,我们将强制执行唯一键。
请注意,与 Python 的 dict
不同,它接受任何不可变值作为键,因为这里的键本质上是属性名称,它们必须是字符串。 (感谢Ted Epstein 的澄清)。此限制可以追溯到json specification 中的pair := string : value
。
【讨论】:
很好的解释 - 希望我早点找到这个!以上是关于为啥 `additionalProperties` 是在 Swagger/OpenAPI 2.0 中表示 Dictionary/Map 的方式的主要内容,如果未能解决你的问题,请参考以下文章