根据HTTP/1.1规范:
该
POST方法用来请求原始服务器接受被附在请求由标识的资源的新下属实体Request-URI的Request-Line
换句话说,POST用于创建.
该
PUT方法请求将所包含的实体存储在提供的实体下Request-URI.如果Request-URI引用已经存在的资源,则封闭的实体应该被视为驻留在源服务器上的实体的修改版本.如果Request-URI未指向现有资源,并且该URI能够被请求用户代理定义为新资源,则源服务器可以使用该URI创建资源.
也就是说,PUT用于创建或更新.
那么,应该使用哪一个来创建资源?或者需要支持两者?
我试图围绕解决基于REST的API中的概念的最佳方式.不包含其他资源的平面资源没有问题.我遇到麻烦的地方是复杂的资源.
例如,我有一本漫画书的资源.ComicBook上有如各种属性author,issue number,date,等.
漫画书也有一份1..n封面清单.这些封面是复杂的对象.它们包含大量关于封面的信息:艺术家,日期,甚至是封面的64位编码图像.
对于GET上ComicBook我可以回相声,和所有的封面,包括他们的base64'ed图像.获得一部漫画可能不是什么大不了的事.但是假设我正在构建一个客户端应用程序,希望在表格中列出系统中的所有漫画.
该表将包含ComicBook资源中的一些属性,但我们当然不希望显示表中的所有封面.返回1000本漫画书,每本漫画书都有多个封面,这将导致大量数据流过网络,在这种情况下,最终用户不需要这些数据.
我的直觉是制作Cover资源并ComicBook包含封面.所以现在Cover是一个URI.GET漫画书现在可以使用,而不是Cover我们为每个封面发回一个URI 的巨大资源,客户可以根据需要检索封面资源.
现在我在创建新漫画方面遇到了问题.当我创建一个时,我肯定想要创建至少一个封面Comic,事实上这可能是一个商业规则.
所以现在我卡住了,我要么强制客户端通过先提交给执行业务规则Cover,获得URI为盖,然后POST荷兰国际集团一个ComicBook与URI列表,或者我POST就ComicBook需要在寻找不同的资源比它吐出出.传入的资源是POST和GET深拷贝,其中传出的GETs包含对依赖资源的引用.
Cover在任何情况下,资源可能都是必要的,因为我确信作为客户,我想在某些情况下解决覆盖方向问题.因此,无论依赖资源的大小如何,问题都以一般形式存在.一般来说,如何处理复杂的资源而不强迫客户只是"知道"这些资源是如何组成的?
我是服务器端Web开发的新手,最近我一直在阅读很多关于实现RESTful API的内容.我仍然坚持的REST API的一个方面是如何构建URI层次结构,以识别客户端可以与之交互的资源.具体来说,我一直在决定如何制作层次结构以及在资源由其他资源类型组成的情况下该怎么做.
这是一个有希望展示我的意思的例子.想象一下,我们有一个Web服务,允许用户从其他用户购买产品.所以在这个简单的例子中,有两个顶级资源用户和产品.这是我开始构建URI层次结构的方式,
对于用户:
/users
/{id}
/location
/about
/name
/seller_rating
/bought
/sold
Run Code Online (Sandbox Code Playgroud)
对于产品:
/products
/{id}
/name
/category
/description
/keywords
/buyer
/seller
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,每个层次结构中的对象都引用另一个层次结构中的对象的子集.例如/users/{id}/bought,某个用户已购买的产品列表,这是其中的一个子集/products.此外,/products/{id}/seller引用销售特定产品的用户.
由于这些URI引用其他对象或其他对象的子集,因此API应该支持以下内容:/users/{id}/bought/id/description和/products/{id}/buyer/location?因为如果支持这些类型的URI,那么什么是阻止这样的东西/users/{id}/bought/{id}/buyer/bought/{id}/seller/name,或者同样令人费解的东西呢?此外,在这种情况下,您将如何处理路由,因为服务器中的路由器必须解释任意长度的URI?
我的问题是在为API目的构建URL时嵌套资源的优势.考虑以下两种用于访问员工资源的备选方案:
/api/employees?department=1 # flat
Vs.
/api/departments/1/employees # nested
Run Code Online (Sandbox Code Playgroud)
现在考虑开发通用库以从API访问REST资源的任务.如果所有路由都是平坦的,那么这样的REST包装器库只需要知道被访问资源的名称:
store.query('employees', {department_id:1}) => /api/employees?department=1
Run Code Online (Sandbox Code Playgroud)
但是,如果我们要支持嵌套路由,那么这个包装器需要知道有关嵌套模型和其他资源的额外信息,以便了解如何构建用于引用此类模型的URL.鉴于并非所有模型都嵌套在相同的父资源下,甚至一些模型根本不会嵌套,REST包装器库需要具有某种配置来描述所有这些额外的知识,否则这些知识是不需要的.
所以我的问题是:
API中的嵌套资源路由是否有任何实际优势?(这并不意味着最终用户使用,因此拥有更漂亮的URL可以获得更少的收益).
嵌套方法是否真的比平面更好,超越美学,以便证明为支持资源URL构建缺乏统一性而引入的额外努力和复杂性?
另见:https://stackoverflow.com/a/36410780/621809
更新:重要的澄清
我从一些评论和答案中了解到,我对一个方面不够清楚:我并不反对使用/employees/5或等URL来处理单个资源/departments/1.我不认为这是嵌套的.
当我说嵌套资源时,我指的是像/departments/1/employees资源一直在另一个资源的上下文中寻址的URL .主要问题是,对于URL构建,通用库需要知道额外的东西,如"员工嵌套在部门下",但"分支不嵌套在任何东西下".如果所有资源都可以通过REST来解决,但是以平面方式解决,知道如何解决它们会更简单,更容易预测.
当您考虑它时,在数据库中,您不需要知道额外的信息,以便知道如何处理对象集合(例如RDMS中的表).您总是将员工集合称为employees,而不是departments/5/employees.
我们正在创建REST API,目前我们有两种方法来定义资源.
基本上我们有Patients,Studies并且Imagesa Patient有n Studies和a Study有n Images.
分层方法
/webapi/patients/0/studies/12/images
Run Code Online (Sandbox Code Playgroud)
层次结构在URI中可见
要搜索所有图像,我们需要搜索资源
/webapi/search?q=imageName:mountain
Run Code Online (Sandbox Code Playgroud)
扁平的方法
/webapi/patients/0
/webapi/studies/12
/webapi/images/
Run Code Online (Sandbox Code Playgroud)
层次结构由属性完成(例如,study 12具有patientId0).
要搜索所有图像,我们可以搜索资源本身:
/webapi/images?q=imageName:mountain
Run Code Online (Sandbox Code Playgroud)
是否有最佳实践方法或者是否有人遇到类似的情况?是一个搜索资源REST还是在平面方法中图像的关系不可见是不好的.
我们还需要考虑移动和修改.
我想实现这样的路线:
/items - list of all items.
/items/types - list of all item types
Run Code Online (Sandbox Code Playgroud)
我正在查看 drf-nester-routs,但嵌套 url 期望 {pk} 被传递。有什么好的方法可以实现我想要的吗?