RESTful、超文本驱动系统需要使客户端能够创建依赖于三种或三种以上不同类型的资源的新资源。公开此功能的最佳方法是什么?
举个例子,假设我经营一家网上商店。服务器知道四个资源:
当订单发出时,客户端需要通过在服务器上创建一个新货件来记录此事件。这批货物将需要对目的地、订单和包装的参考。
为了实现新发货的创建,我可以想到三种方法,但我不喜欢它们中的任何一种:
我不喜欢选项1,因为装运媒体类型还定义了指向订单、封隔器和目的地的链接。在这里,"link“是一个JSON散列,由一个人类可读的名称、一个URI和一个媒体类型组成。在媒体类型中添加"order_uri“、"packer_uri”和"destination_uri“似乎不太枯燥,因为它重复了相关资源的URI。
选项2使用了深度嵌套的URI,它既不能很好地维护,也不能捕获任何有意义的层次信息。
选项3在客户端和货件创建之间设置了另一个抽象级别,这使得系统更难学习。
如果一批货物只依赖于另一种资源,那么选项2就更有意义了,但在这种情况下就不是了。就目前情况而言,我赞成备选案文3,但更倾向于更好的选择。
在本例中,创建新托运的URI和媒体类型的最佳组合是什么?还应考虑采取哪些其他办法?
更新:下面是装运资源的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"
}
}
“托运”哈希(减去"created_at“字段)的内容将得到POSTed。使用GET时,将发送上述完整的货件表示。
发布于 2009-09-09 16:13:43
REST“层次结构”没有任何意义。它们为导航以路径的形式显示关系提供了方便。不是层级本身,而是一条道路。因此,如果您放弃了“层次结构”概念,并认识到到同一最终位置有许多替代路径,则选项2实际上是明智的。
您的选择2是一个订单->包装->目的地路径。理论上,订单->目的地->包装和包装->订单->目的地,包装->目的地->订单,以及少数其他所有领导相同的地方。是的,支持他们是件痛苦的事。然而,这证明了它们都是等价的,而且没有等级制度。
“我不喜欢选项1,因为它看起来不太干燥。”
所以?省去那些重复的东西。为什么一批货物还必须包含订单和封隔器信息的完整重复?URI引用足以允许查找和检索Order和Packer。为什么要发订单和封隔器?
“选项3使系统更难学习。”为了谁?开发商?您的系统是围绕开发人员设计的,而不是用户和他们的用例?惭愧。
REST的要点是(通常) URI是绝对的、最终的和永恒的。哪种选择为您提供了绝对最佳的URI结构?请注意,URI不是层次结构,而是路径--对象可以存在于多个可选路径的末尾。
你在制造一批货。发到/shipment
。简单、清晰的URI才是最重要的。
发布于 2009-09-09 18:33:11
好吧,现在我知道你在哪里看到复制了。张贴以下内容是否可行?
{
"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",
}
}
}
把这个还给我
{
"shipment":{
"created_at": "Wed Sep 09 18:38:31 -0700 2009",
"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"
}
}
}
也许这只是在JSON中不起作用,但是我在我的资源中对XML做了类似的事情。其思想是,您可以向服务器传递一个对资源的“引用”,只需填写uri,服务器就可以填充对象中的其余数据。
发布于 2013-12-02 02:36:16
我认为option1和option2是公平的解决方案,我会忘记option3,因为以前的解决方案更好。
客户端应该始终通过检查链接的语义(例如链接关系和特定于供应商的MIME类型)来决定,而不是通过检查URL结构来决定。您不一定需要特定于供应商的MIME类型,您可以使用和RDF格式,如JSON-LD、REST和应用程序特定的语音来描述您的链接及其输入字段,例如Hydra。您也可以使用自定义解决方案,例如将_fields添加到_links。
复制的链接没有什么问题。如果消息大小太大,可以使用gzip。顺便说一句,不要把URL和链接混为一谈,它们是不同的东西。URL是资源标识符,链接是对资源的可能操作调用。
https://stackoverflow.com/questions/1402721
复制相似问题