几天前有人问我这个问题,我没有答案:
HTTP是一个无状态的协议,当我们打开www.google.com时,是否可以称之为REST调用?
我所想的:
当我们对google.com进行搜索时,所有信息都通过cookie和URL参数传递。它看起来像一个无状态的请求。但是搜索结果并不独立于用户过去的请求。搜索结果特定于用户的兴趣和行为。现在,它看起来不像一个无状态的请求。
我知道这是一个古老的问题,我读过很多SO的答案,比如为什么HTTP是无状态协议?但我仍然无法理解当用户活动被跟踪时会发生什么,比如在谷歌或亚马逊(基于过去购买的推荐)或任何其他基于用户活动的推荐网站上。
它是RESTful还是RESTless?
如果我想创建一个使用REST架构并仍然提供特定于用户的响应的Web应用程序怎么办?
HTTP是无状态的,但是谷歌应用层不是。特定的Cookie及其含义是应用层的一部分。
考虑TCP/IP。IP是无状态协议,但TCP不是。IP包中嵌入的TCP中存在状态并不意味着IP协议本身具有状态。
所以这是Rest电话吗?没有。
虽然HTTP无国籍
但是应用层不是无状态的。REST的原则之一是系统不会为了修改响应而在请求之间保留关于客户端的状态数据。在谷歌的例子中,这显然不会发生。
“无国籍”的含义似乎被(假设地)超越了其实际表达。
考虑一个完全没有DB的Web系统。你调用(RESTful)API,你总是得到完全相同的结果。这是完全无状态的…但这也完全不是一个真正的系统。
实际上,在每个实现中,一个真实的系统都保存着数据。此外,这些数据是RESTfulAPI允许我们访问的“资源”。当然,数据也会因API调用而改变。因此,如果您获取资源的值,更改其值,然后再次获取其值,您将获得与第一次读取不同的值;然而,这显然并不是说读取本身不是无状态的。它们是无状态的,因为它们代表每次调用的相同操作(或者更确切地说,资源)。更改必须手动完成,使用另一个RESTfulAPI来更改资源值,然后将反映在下一次调用中。
然而,如果我们有一个资源在没有手动、标准API动词的情况下发生变化,情况会怎样呢?例如,假设我们有一个资源计算其他资源被访问的次数。或者其他一些资源正在从其他一些第三方数据中填充。显然,这仍然是一个无状态协议。
此外,从某种意义上说,几乎任何系统——例如,任何包含身份验证机制的系统——对相同的API调用的响应都不同,这取决于用户的权限。然而,很明显,RESTful系统并没有被禁止对其用户进行身份验证…
简而言之,为了该协议,无状态系统是无状态的。如果谷歌跟踪调用,这样如果我在同一个会话中调用相同的资源,我会得到不同的答案,那么它就打破了无状态要求。但是只要返回的响应由于应用程序级别的数据而不同,并且与会话无关,这个要求就不会被打破。
AFAIK,Google所做的不一定与会话相关。如果同一个用户在完全相同的条件下(例如,IP、地理位置、OS、浏览器等)运行相同的搜索,他们将得到完全相同的响应。如果一个新的相同搜索由于Google在最后一次调用中“学到”的内容而产生不同的结果,它仍然是无状态的,因为——同样——如果在另一个会话中进行,但在相同的条件下,第二次调用会产生完全相同的结果。
你可能应该从菲尔丁在论文中对饼干的评论开始,然后回顾菲尔丁在Rest讨论上发表的进一步想法。
我对菲尔丁想法的解释,适用于这个问题:不,这不是REST。搜索结果根据请求中cookie标头的状态而变化,也就是说资源的表示根据cookie而变化,也就是说资源的部分标识符被捕获在cookie标头中。
cookie的大多数问题都是由于破坏可见性造成的,这会影响缓存和超文本应用程序引擎——Fielding,2003
碰巧的是,缓存似乎不是Google的重中之重;返回的表示包含一个缓存控制私有标头,这限制了中间组件的参与。