API 回复:在同一回复中引用是不好的做法?
API responses: references inside the same response is a bad practice?
在我的工作中,多年来我一直在处理这个请求,它给了我们这样的响应(是一个简短的例子,许多字段被切断):
{
"catalog": {
"categories": [
{
"id": "firstCategory",
"name": "The first category!",
"order": 0,
"offers": [
{
"id": "offer1" // a LOT of fields
},
{
"id": "offer2" // a LOT of fields
},
{
"id": "offer3" // a LOT of fields
}
]
},
{
"id": "secondCategory",
"name": "The second category!",
"order": 0,
"offers": [
{
"id": "offer2" // a LOT of fields ... same again
},
{
"id": "offer3" // a LOT of fields ... same again
},
{
"id": "offer4" // a LOT of fields
}
]
},
{
"id": "thirdCategory",
"name": "The third category!",
"order": 0,
"offers": [
{
"id": "offer1" // a LOT of fields ... same again
},
{
"id": "offer4" // a LOT of fields ... same again
},
{
"id": "offer5" // a LOT of fields
}
]
}
]
}
}
如您所见,我们有一定数量的类别(在我的日常中是 5-15 个)包含一些优惠(类别 10-30 个)。
很多时候这些优惠在不同类别中重复出现:这些优惠完全相同(firstCategory 中 id="offer1" 的优惠与 thirdCategory 中 id="offer1" 的优惠完全相同)。
这种情况经常发生,似乎这还不够,一个 Offer 元素包含许多字段(大约 50 个……在我的示例中,我出于明显的原因将它们删除):这会导致非常大的响应.
我想知道尝试通过这样设置的参考系统来解决问题是否是正确的做法:
{
"catalog": {
"categories": [
{
"id": "firstCategory",
"name": "The first category!",
"order": 0,
"idOffers": [ "offer1", "offer2", "offer3" ]
},
{
"id": "secondCategory",
"name": "The second category!",
"order": 1,
"idOffers": [ "offer2", "offer3", "offer4" ]
},
{
"id": "thirdCategory",
"name": "The third category!",
"order": 2,
"idOffers": [ "offer1", "offer4", "offer5" ]
}
],
"offers": [
{
"id": "offer1" // a LOT of fields... but written only once
},
{
"id": "offer2" // a LOT of fields... but written only once
},
{
"id": "offer3" // a LOT of fields... but written only once
},
{
"id": "offer4" // a LOT of fields... but written only once
},
{
"id": "offer5" // a LOT of fields... but written only once
}
]
}
}
虽然我觉得它更实用、更简洁,但我想知道的是:这是一种不好的做法吗?
PS:如果有人想知道提出 GET catalog/categories
和 GET catalog/{idCategory}/offers
这样的两个请求是否更正确
或类似的东西,他必须知道出于各种业务和体系结构原因,必须只提出一个请求。
你的建议本质上没有错;这很可能是一种更好的方法。除了减少有效负载大小的明显好处外,您的建议还将消除数据异常的可能性。现有结构中可能会出现异常,因为它允许同一报价的两个不同 'copies' 具有不相符的 属性 值。如果您不完全完全信任数据源,那么您可能会觉得需要验证传入的报价。但是你甚至不能这样做,因为(比方说)offer1 的许多副本中,你认为哪个副本是 'master' 副本?
正是出于这个原因,Ted Codd 发明了First Normal Form,被通俗地概括为“消除重复组”。
我说这个 可能 是一个更好的方法,但它是否真的 是 更好的方法在一定程度上取决于你的上下文.例如,如果您想立即将此数据存储在关系数据库中,那么这绝对是一种更好的方法,因为规范化已被推到上游,可能回到源头,但肯定在您的应用程序范围之外,这意味着您不需要不必担心上述异常情况,而且您要处理的数据更少。
另一方面,如果您想要生成分层报告 - 或者将数据存储在类似于您收到的分层结构中,那么就不是那么明确了。我仍然认为消除异常风险是一个很大的收获,有效载荷大小可能会大幅减少,但您可能会付出代价,因为必须在某处缓存报价,然后必须 'look up' 报价数据当您处理每个 idOffers
数组时。如果性能因此受到严重影响,您可能需要权衡这些因素。如果报价相对较少,我怀疑这会是一个问题。
所以我认为你的直觉是正确的。
在我的工作中,多年来我一直在处理这个请求,它给了我们这样的响应(是一个简短的例子,许多字段被切断):
{
"catalog": {
"categories": [
{
"id": "firstCategory",
"name": "The first category!",
"order": 0,
"offers": [
{
"id": "offer1" // a LOT of fields
},
{
"id": "offer2" // a LOT of fields
},
{
"id": "offer3" // a LOT of fields
}
]
},
{
"id": "secondCategory",
"name": "The second category!",
"order": 0,
"offers": [
{
"id": "offer2" // a LOT of fields ... same again
},
{
"id": "offer3" // a LOT of fields ... same again
},
{
"id": "offer4" // a LOT of fields
}
]
},
{
"id": "thirdCategory",
"name": "The third category!",
"order": 0,
"offers": [
{
"id": "offer1" // a LOT of fields ... same again
},
{
"id": "offer4" // a LOT of fields ... same again
},
{
"id": "offer5" // a LOT of fields
}
]
}
]
}
}
如您所见,我们有一定数量的类别(在我的日常中是 5-15 个)包含一些优惠(类别 10-30 个)。 很多时候这些优惠在不同类别中重复出现:这些优惠完全相同(firstCategory 中 id="offer1" 的优惠与 thirdCategory 中 id="offer1" 的优惠完全相同)。
这种情况经常发生,似乎这还不够,一个 Offer 元素包含许多字段(大约 50 个……在我的示例中,我出于明显的原因将它们删除):这会导致非常大的响应.
我想知道尝试通过这样设置的参考系统来解决问题是否是正确的做法:
{
"catalog": {
"categories": [
{
"id": "firstCategory",
"name": "The first category!",
"order": 0,
"idOffers": [ "offer1", "offer2", "offer3" ]
},
{
"id": "secondCategory",
"name": "The second category!",
"order": 1,
"idOffers": [ "offer2", "offer3", "offer4" ]
},
{
"id": "thirdCategory",
"name": "The third category!",
"order": 2,
"idOffers": [ "offer1", "offer4", "offer5" ]
}
],
"offers": [
{
"id": "offer1" // a LOT of fields... but written only once
},
{
"id": "offer2" // a LOT of fields... but written only once
},
{
"id": "offer3" // a LOT of fields... but written only once
},
{
"id": "offer4" // a LOT of fields... but written only once
},
{
"id": "offer5" // a LOT of fields... but written only once
}
]
}
}
虽然我觉得它更实用、更简洁,但我想知道的是:这是一种不好的做法吗?
PS:如果有人想知道提出 GET catalog/categories
和 GET catalog/{idCategory}/offers
这样的两个请求是否更正确
或类似的东西,他必须知道出于各种业务和体系结构原因,必须只提出一个请求。
你的建议本质上没有错;这很可能是一种更好的方法。除了减少有效负载大小的明显好处外,您的建议还将消除数据异常的可能性。现有结构中可能会出现异常,因为它允许同一报价的两个不同 'copies' 具有不相符的 属性 值。如果您不完全完全信任数据源,那么您可能会觉得需要验证传入的报价。但是你甚至不能这样做,因为(比方说)offer1 的许多副本中,你认为哪个副本是 'master' 副本?
正是出于这个原因,Ted Codd 发明了First Normal Form,被通俗地概括为“消除重复组”。
我说这个 可能 是一个更好的方法,但它是否真的 是 更好的方法在一定程度上取决于你的上下文.例如,如果您想立即将此数据存储在关系数据库中,那么这绝对是一种更好的方法,因为规范化已被推到上游,可能回到源头,但肯定在您的应用程序范围之外,这意味着您不需要不必担心上述异常情况,而且您要处理的数据更少。
另一方面,如果您想要生成分层报告 - 或者将数据存储在类似于您收到的分层结构中,那么就不是那么明确了。我仍然认为消除异常风险是一个很大的收获,有效载荷大小可能会大幅减少,但您可能会付出代价,因为必须在某处缓存报价,然后必须 'look up' 报价数据当您处理每个 idOffers
数组时。如果性能因此受到严重影响,您可能需要权衡这些因素。如果报价相对较少,我怀疑这会是一个问题。
所以我认为你的直觉是正确的。