一个 RESTful,hypertext-driven系统需要使客户端能够创建依赖于三个或更多不同类型资源的新资源。公开此功能的最佳方法是什么?
例如,假设我经营一家在线商店。服务器知道四种资源:
当订单发货时,客户端需要通过在服务器上创建一个新的发货来记录此事件。货件将需要提及目的地、订单和包装商。
实现新Shipments的创建,我可以想到三种方法,我不喜欢它们中的任何一种:
我不喜欢选项 1,因为 Shipment 媒体类型另外定义了到 Order、Packer 和 Destination 的链接。这里,“链接”是一个 JSON 散列,由一个人类可读的名称、一个 URI 和一个媒体类型组成。向媒体类型添加“order_uri”、“packer_uri”和“destination_uri”似乎不是很枯燥,因为它复制了关联资源的 URI。
选项 2 使用深度嵌套的 URI,它看起来既不易于维护,也无法捕获任何有意义的分层信息。
选项 3 在客户端和 Shipments 的创建之间放置了另一个抽象级别,这使得系统更难学习。
如果 Shipment 仅依赖于一种其他资源,则选项 2 会更有意义,但在这种情况下并非如此。就目前而言,我赞成选项 3,但更喜欢更好的选择。
在此示例中,创建新 Shipment 的 URI 和媒体类型的最佳组合是什么?还应该考虑哪些其他方法?
更新:以下是 Shipment 资源的 JSON 示例表示,显示订单、包装商和目的地的链接。选项 1 所需的 URI 重复出现在“装运”哈希中:
{
"shipment":{
"created_at": "Wed Sep 09 18:38:31 -0700 2009",
"order_uri":"http://example.com/orders/815",
"packer_uri":"http://example.com/packers/42",
"destination_uri":"http://example.com/destinations/666"
},
"order":{
"name":"the order to which this shipment belongs",
"uri":"http://example.com/orders/815",
"media_type":"application/vnd.com.example.store.Order+json"
},
"packer":{
"name":"the person who packed this shipment",
"uri":"http://example.com/packers/42",
"media_type":"application/vnd.com.example.store.Packer+json"
},
"destination":{
"name":"the destination of this shipment",
"uri":"http://example.com/destinations/666",
"media_type":"application/vnd.com.example.store.Destination+json"
}
}
“shipment”散列的内容(减去“created_at”字段)将被发布。使用 GET 时,将发送上面的完整 Shipment 表示。
最佳答案
REST“层次结构”没有任何意义。它们便于导航以路径的形式显示关系。本身不是层次结构,而是路径。因此,如果您放弃“层次结构”概念并认识到有许多通往同一最终位置的替代路径,则选项 2 实际上是明智的。
您的选项 2 是 orders->packers->destination 路径。理论上,orders->destinations->packers和packers->orders->destinations,packers->destinations->orders,以及其他几个都在同一个地方。是的,支持他们所有人是一种痛苦。然而,这证明它们都是等价的,并且没有等级。
“我不喜欢选项 1,因为 [它] 看起来不是很干燥。”
所以?去掉重复的东西。为什么 cargo 还必须包含订单和包装商信息的完整重复? URI 引用足以允许查找和检索 Order 和 Packer。为什么要发送 Order 和 Packer?
“选项 3 使系统更难学习。”为了谁?开发商?您是围绕开发人员而不是用户及其用例设计系统吗?耻辱。
REST 的要点是(通常)一个 URI 是一个绝对的、最终的和永恒的东西。哪种替代方案为您提供了绝对最佳的 URI 结构?认识到 URI 不是层次结构而是路径——并且对象可以存在于多个替代路径的末尾。
您正在创建货件。发布到 /shipment
.简单、清晰的 URI 才是最重要的。
关于REST:如何创建依赖于三个或更多不同类型资源的资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1402721/