我们都知道通过REST删除单个项目的"标准"方法是向URI发送单个DELETE请求example.com/Items/666.盛大,让我们马上删除很多.因为我们不需要原子删除(或真正的交易,即全部或全部),我们可以告诉客户"运气不好,提出许多请求",但这不是很好.因此,我们需要一种方法来允许客户端请求立即删除许多"项目".
根据我的理解,这个问题的"典型"解决方案是"两步"方法.首先,客户端POST一个项目ID列表,并返回一个URI,如example.com/Items/Collection/1.创建该集合后,它们会调用DELETE.
现在,我看到这很好用,除了我,这是一个糟糕的解决方案.首先,您强制客户端发出两个容纳服务器的请求.其次,'我以为DELETE应该删除一个Item?',不应该在这个URI上调用DELETE有效地取消事务(虽然它不是真正的事务),我们怎么会取消它?真的会更好,如果有某种形式的"执行"的行动,但我不能捣乱是很大.它还强制服务器必须考虑'POSTed的JSON看起来更像是修改这些Item的请求,但请求是DELETE ...所以我想我会删除它们'.这种方法也开始在客户端/服务器上强加一种状态,而不是我承认的真实状态,但它有点像.
在我看来,更好的解决方案是简单地调用DELETE example.com/Items(或者可能example.com/Items/Collection暗示这是多次删除)并传递包含您要删除的ID列表的JSON数据.据我所知,这基本上解决了第一种方法的所有问题.它更容易用作客户端,减少服务器必须完成的工作,真正无状态,更具语义性.
我真的很感激这方面的反馈,我错过了一些关于REST的东西,这使得我对这个问题的解决方案不切实际吗?我还希望链接到文章,特别是如果他们比较这两种方法; 我知道这通常不被批准用于SO.我需要能够反驳说只有第一种方法才是真正的RESTfull,证明第二种方法是可行的解决方案.当然,如果我正在咆哮错误的树,请告诉我.
the*_*man 25
我花了大约一个星期左右的时间阅读REST,并且据我所知,将这些解决方案中的任何一个描述为"RESTfull"是错误的,而你应该说'这两个解决方案都不符合REST手段'.
简短的回答就是,如Roy Fielding的论文(参见第5章)所述,REST 并未涵盖如何在REST庄园中删除资源(单数或多数)的主题.没错,没有'正确的RESTful方式来删除资源'......好吧,不完全.
REST本身并没有定义如何删除资源,但它确实定义了您正在使用的协议(请记住REST不是协议)将决定如何执行这些操作.协议通常是HTTP; "通常"是菲尔丁指出的关键词, REST不是HTTP的同义词.
所以我们期待HTTP说出哪种方法是"正确的".遗憾的是,就HTTP而言,这两种方法都是可行的.是的'可行'.HTTP将允许客户端发送带有效负载的POST请求(以创建集合资源),然后在此新集合上调用DELETE方法以删除资源; 它还允许您在单个DELETE方法的有效负载内发送数据以删除资源列表.HTTP只是您向服务器发送请求的媒介,它将由服务器进行适当的响应.对我来说,HTTP协议似乎对某些地方的解释比较开放,但似乎确实为行动的意思,应该如何处理以及应该给出什么样的回应制定了相当明确的指导方针; 这只是'你应该这样做'而不是'
有些人认为"两阶段"方法不可能是"REST",因为服务器必须为客户端存储"状态"以执行第二个操作.这只是对某些部分的误解.必须理解的是,客户端和服务器都没有在被POST的列表之间存储关于另一个的任何"状态"信息,然后随后被删除.是的,列表必须在删除之前创建,但是服务器不记得它是客户端alpha来制作此列表(这样的方法将允许客户端简单地调用'DELETE'作为下一个请求并且服务器记住使用该列表,这根本就不是无状态的)因此,客户端必须告诉服务器删除该特定列表,列表给它一个特定的URI.如果客户端试图删除一个尚不存在的集合列表,则只会告诉"无法找到资源"(最有可能是经典的404错误).如果您希望声称这两步方法确实维护状态,您还必须声明只需要获取URI就需要一个状态,因为URI必须首先存在.声称持续存在这种"状态"是对"状态"意味着什么的误解.而且,作为进一步"证明"这样的两阶段方法确实是无状态的,您可以非常高兴地在列表中使用客户端alpha POST并且稍后客户端测试版(没有与其他客户端进行任何通信)在列表资源上调用DELETE.(最有可能是经典的404错误).如果您希望声称这两步方法确实维护状态,您还必须声明只需要获取URI就需要一个状态,因为URI必须首先存在.声称持续存在这种"状态"是对"状态"意味着什么的误解.而且,作为进一步"证明"这样的两阶段方法确实是无状态的,您可以非常高兴地在列表中使用客户端alpha POST并且稍后客户端测试版(没有与其他客户端进行任何通信)在列表资源上调用DELETE.(最有可能是经典的404错误).如果您希望声称这两步方法确实维护状态,您还必须声明只需要获取URI就需要一个状态,因为URI必须首先存在.声称持续存在这种"状态"是对"状态"意味着什么的误解.而且,作为进一步"证明"这样的两阶段方法确实是无状态的,您可以非常高兴地在列表中使用客户端alpha POST并且稍后客户端测试版(没有与其他客户端进行任何通信)在列表资源上调用DELETE.
我认为,只有在DELETE请求的有效负载中发送列表的第二个选项是无状态的,这是非常明显的.完成请求所需的所有信息都完全存储在一个请求中.
可以说,DELETE操作只应在"有形"资源上调用,但在这样做时,你公然忽略了REST的REpresentational部分; 这就是名字!代表性的方面是'允许'URI,例如http://example.com/myService/timeNow,一个URI,当'got'将动态地返回当前时间,而不必加载某个文件或从某个数据库读取.关键概念是URI不直接映射到某些"有形"数据.
然而,必须质疑无国籍性质的一个方面.正如Fielding在5.1.3节中描述的"客户端无状态服务器",他指出:
We next add a constraint to the client-server interaction: communication must
be stateless in nature, as in the client-stateless-server (CSS) style of
Section 3.4.3 (Figure 5-3), such that each request from client to server must
contain all of the information necessary to understand the request, and
cannot take advantage of any stored context on the server. Session state is
therefore kept entirely on the client.
Run Code Online (Sandbox Code Playgroud)
我眼中的关键部分是"无法利用服务器上存储的任何上下文".现在我将告诉你,"背景"对解释有些开放.但我发现很难看出你如何考虑存储一个列表(在内存或磁盘上),用于提供实际有用的含义不会违反这个"规则".没有这个'列表上下文',DELETE操作没有任何意义.因此,我只能得出结论,使用两步方法来执行诸如删除多个资源之类的操作不能也不应该被认为是"RESTfull".
我也有点吝啬必须付出的努力,无论是为此寻找论据.整个互联网似乎已经被这个想法所笼罩,两步法是"RESTfull"做这种行为的方式,其理由是"它是RESTfull的做法".如果您退出其他人正在做的事情,您会发现任何一种方法都需要发送相同的列表,因此可以从参数中忽略它.这两种方法都是"代表性的"和"无国籍的".唯一真正的区别是,由于某种原因,一种方法决定需要两个请求.这两个请求随后会出现后续问题,例如"您为多长时间保留数据"以及"客户端如何告诉服务器它不再需要此集合,
所以,在某种程度上,我用同样的问题回答我的问题,'为什么你会考虑采取两步走的方法?'
| 归档时间: |
|
| 查看次数: |
8323 次 |
| 最近记录: |