API 设计:未记录的对象键与对象数组
API Design: Undocumented object keys vs. Array of Objects
对于这个 JSON API 设计问题,我有一组任意的键值对需要在 API Request/Response 主体中提供。键和值都是未知的。构建此结构的最佳方式是什么?
据我所知,有两种方法可以实现:
1。未记录的对象键
{
"fruit": "Apple",
"sport": "Hockey",
...
"keyN": "valueN"
}
- 优点:非常干净,应用程序逻辑易于解析
- 缺点:无法正确记录此对象 - 对象的形状是无限任意的。
2。对象数组
[
{
"key": "fruit",
"value": "Apple"
},
{
"key": "sport",
"value": "Hockey"
},
...
{
"key": "keyN",
"value": "valueN"
}
]
- 优点:易于记录和理解为具有已知结构的对象数组。
- 缺点:应用程序逻辑会更冗长。
构造此文件的最佳方法是什么?
注意:这是关于 API 文档的问题,而不是关于应用程序逻辑的问题。如上所述,我很清楚#1 是代码操作的最佳解决方案。但我还不清楚如何在 API 文档中以始终被正确解释的方式记录这一点
更好的解决方案是:
2。对象数组
[
{
"key": "fruit",
"value": "Apple"
},
{
"key": "sport",
"value": "Hockey"
},
...
{
"key": "keyN",
"value": "valueN"
}
]
数组是涉及任意长度时使用的正确模式。这更冗长但更容易理解。赞成冗长。
我非常非常强烈推荐#1。 #2 是一种变态。您的数据结构是一本字典。不用数组来实现字典,却有一半的特性。
想一想:你说你不能记录#1。那么你打算如何记录#2?如果 #1 不得包含键 "strawberry",您如何证明 #2 不得包含具有键 = "key"、值 = [=18 的(键,值)对的字典=]?
如何检查#1 或#2 是否包含键 "fruit" 以及值是多少? #1 是直接访问。字典 ["fruit"]。在 #2 中,您需要遍历数组元素,检查它们是否都是字典,检查是否有一个带有条目键的字典:"fruit",检查它是否有另一个条目 "value"。也许如果您按代码行付费,您就会这样做。
有趣的是,三个完全不同的答案,每个都有反对票。显然至少有两个反对者是愚蠢的。
就文档而言,我个人认为#1 和#2 之间没有太大区别。如果字段未知,那么空 map/object 与空数组并不重要。
我看到它被称为 'Json Junk Drawer'。
我看到的一个补充是 map/object 特定于 'Json Junk Drawer',例如:
{
"fieldsThatDontChange" : "example",
"attributes" :{
"unknownfield" : "unknown"
}
}
这真的是一个反模式。但是这里的一个小好处是您可以告诉客户属性部分是放置他们未记录的东西的地方。例如,如果这是一个用例,甚至可以在属性部分强制执行客户端特定模式。
这里有一些关于 JSON 垃圾抽屉的更多信息,其中有一些指向讨论该主题的 YouTube 视频的链接:
对于这个 JSON API 设计问题,我有一组任意的键值对需要在 API Request/Response 主体中提供。键和值都是未知的。构建此结构的最佳方式是什么?
据我所知,有两种方法可以实现:
1。未记录的对象键
{
"fruit": "Apple",
"sport": "Hockey",
...
"keyN": "valueN"
}
- 优点:非常干净,应用程序逻辑易于解析
- 缺点:无法正确记录此对象 - 对象的形状是无限任意的。
2。对象数组
[
{
"key": "fruit",
"value": "Apple"
},
{
"key": "sport",
"value": "Hockey"
},
...
{
"key": "keyN",
"value": "valueN"
}
]
- 优点:易于记录和理解为具有已知结构的对象数组。
- 缺点:应用程序逻辑会更冗长。
构造此文件的最佳方法是什么?
注意:这是关于 API 文档的问题,而不是关于应用程序逻辑的问题。如上所述,我很清楚#1 是代码操作的最佳解决方案。但我还不清楚如何在 API 文档中以始终被正确解释的方式记录这一点
更好的解决方案是:
2。对象数组
[
{
"key": "fruit",
"value": "Apple"
},
{
"key": "sport",
"value": "Hockey"
},
...
{
"key": "keyN",
"value": "valueN"
}
]
数组是涉及任意长度时使用的正确模式。这更冗长但更容易理解。赞成冗长。
我非常非常强烈推荐#1。 #2 是一种变态。您的数据结构是一本字典。不用数组来实现字典,却有一半的特性。
想一想:你说你不能记录#1。那么你打算如何记录#2?如果 #1 不得包含键 "strawberry",您如何证明 #2 不得包含具有键 = "key"、值 = [=18 的(键,值)对的字典=]?
如何检查#1 或#2 是否包含键 "fruit" 以及值是多少? #1 是直接访问。字典 ["fruit"]。在 #2 中,您需要遍历数组元素,检查它们是否都是字典,检查是否有一个带有条目键的字典:"fruit",检查它是否有另一个条目 "value"。也许如果您按代码行付费,您就会这样做。
有趣的是,三个完全不同的答案,每个都有反对票。显然至少有两个反对者是愚蠢的。
就文档而言,我个人认为#1 和#2 之间没有太大区别。如果字段未知,那么空 map/object 与空数组并不重要。
我看到它被称为 'Json Junk Drawer'。
我看到的一个补充是 map/object 特定于 'Json Junk Drawer',例如:
{
"fieldsThatDontChange" : "example",
"attributes" :{
"unknownfield" : "unknown"
}
}
这真的是一个反模式。但是这里的一个小好处是您可以告诉客户属性部分是放置他们未记录的东西的地方。例如,如果这是一个用例,甚至可以在属性部分强制执行客户端特定模式。
这里有一些关于 JSON 垃圾抽屉的更多信息,其中有一些指向讨论该主题的 YouTube 视频的链接: