RESTful,超文本驱动的系统需要使客户端能够创建依赖于三种或更多不同类型资源的新资源.揭示此功能的最佳方法是什么?
举个例子,假设我经营一家在线商店.服务器知道四种资源:
订单发货时,客户需要通过在服务器上创建新的货件来记录此事件.货件将需要参考目的地,订单和包装工.
为了实现新货物的创建,我可以想到三种方法,我不喜欢它们中的任何一种:
我不喜欢选项1,因为Shipment媒体类型还定义了Order,Packer和Destination的链接.这里,"链接"是由人类可读的名称,URI和媒体类型组成的JSON哈希.将"order_uri","packer_uri"和"destination_uri"添加到媒体类型似乎不是很干,因为它复制了相关资源的URI.
选项2使用深度嵌套的URI,这些URI看起来既不易维护也不捕获任何有意义的分层信息.
选项3在客户端和Shipments的创建之间进行了另一层抽象,这使得系统更难学习.
如果发货仅依赖于另一个资源,则选项2会更有意义,但在这种情况下不会.就目前而言,我赞成选项3,但更喜欢更好的东西.
在此示例中,创建新货件的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"
}
}
Run Code Online (Sandbox Code Playgroud)
"发货"哈希的内容(减去"created_at"字段)将被POST.使用GET时,将发送上面的完整发货表示.
REST“层次结构”没有任何意义。它们为导航提供了便利,以路径的形式显示关系。本身不是层次结构,而是路径。因此,如果您放弃“层次结构”概念并认识到存在许多通往同一最终位置的替代路径,那么选项 2 实际上是明智的。
您的选项 2 是订单 -> 打包机 -> 目标路径。理论上,订单->目的地->打包机和打包机->订单->目的地、打包机->目的地->订单以及其他一些都通向同一个地方。是的,支持他们所有人是一种痛苦。然而,这证明它们都是等效的并且没有层次结构。
“我不喜欢选项 1,因为它看起来不太干。”
所以?去掉重复的东西。为什么货物还必须包含完整重复的订单和包装信息?URI 引用足以允许查找和检索 Order 和 Packer。为什么要发送订单和打包机?
“选项 3 使系统更难学习。” 为了谁?开发商?您正在围绕开发人员设计系统,而不是用户及其用例?耻辱。
REST 的要点(通常)是 URI 是绝对的、最终的和永恒的东西。哪种替代方案可以为您提供绝对最佳的 URI 结构?认识到 URI 不是层次结构而是路径——并且对象可以存在于多个替代路径的末尾。
您正在创建一个货件。发布到/shipment. 简单、清晰的 URI 才是最重要的。