我需要一些澄清。我一直在阅读关于REST和构建基于REST的应用程序的书籍。根据维基百科,REST本身被定义为具象状态传输。因此,我不理解所有这些无国籍的官样文章,每个人都在不停地吐出来。

从维基百科:

在任何特定的时间,客户端可以处于之间的转换 应用程序处于“静止”状态。处于休息状态的客户端可以 与用户交互,但不创建负载,也不消耗每个客户端 服务器集或网络上的存储。

他们只是说不要使用会话/应用程序级数据存储吗?

我知道REST的一个目标是使URI访问一致且可用,例如,不是在帖子中隐藏分页请求,而是使请求的页码成为get URI的一部分。对我来说很有道理。但是,说每个客户端数据(会话数据)都不应该存储在服务器端似乎有点过头了。

如果我有一个消息队列,而我的用户想要读取消息,但在读取消息时,又想在会话期间阻止某些发送者的消息通过,该怎么办?将其存储在服务器端的某个位置,并让服务器只发送未被用户阻止的消息(或消息ID),这难道不合理吗?

每次请求新的消息列表时,我真的必须发送整个消息发送者列表来阻止吗?与我相关的消息列表在一开始就不应该是公开可用的资源。

我只是想理解一下。谁来澄清一下。


更新:

我发现了一个堆栈溢出的问题,它的答案并不能让我一直走到那里: 如何在REST中管理状态 这说明客户端状态很重要,应该在每个请求上都传输....Ugg . .看起来开销很大…这样对吗??


当前回答

用户应用程序状态管理的历史视图

传统意义上的会话将用户的状态保存在服务器内部的应用程序中。这可能是流中的当前页面,也可能是先前已输入但尚未持久化到主数据库中的内容。

这种需求的原因是客户端缺乏有效维护状态的标准,而不需要特定于客户端(即特定于浏览器)的应用程序或插件。

随着时间的推移,HTML5和XML Header Request已经标准化了在客户端(即浏览器端)以标准方式存储包括应用程序状态在内的复杂数据的概念,而无需在服务器之间来回传输。

REST服务的一般使用

REST服务通常在需要执行事务或需要检索数据时调用。

REST服务应该由客户端应用程序调用,而不是由最终用户直接调用。

进行身份验证

对于任何对服务器的请求,请求的一部分应该包含授权令牌。它是如何实现的是特定于应用程序的,但通常是BASIC或CERTIFICATE形式的身份验证。

Form based authentication is not used by REST services. However, as noted above REST services are not meant to be called by the user, but by the application. The application needs to manage getting the authentication token. In my case I used cookies with JASPIC with OAuth 2.0 to connect to Google for authentication and simple HTTP Authentication for automated testing. I also used HTTP Header authentication via JASPIC for local testing as well (though the same approach can be performed in SiteMinder)

根据这些示例,身份验证是在客户端进行管理的(尽管SiteMinder或谷歌将在其端存储身份验证会话),对于该状态无法做任何事情,但它不是REST服务应用程序的一部分。

检索请求

REST中的检索请求是GET操作,其中请求特定的资源并且是可缓存的。不需要服务器会话,因为请求拥有检索数据所需的一切:身份验证和URI。

事务脚本

如上所述,客户端应用程序本身调用REST服务以及它在客户端管理的身份验证。

这对于REST服务(如果操作正确的话)意味着将单个请求发送到REST服务器,该服务器将包含单个用户操作所需的所有内容,该操作执行单个事务所需的所有内容,事务脚本就是该模式的名称。

这通常通过POST请求来完成,但也可以使用其他请求,如PUT。

很多人为的REST示例(我自己做过)试图尽可能多地遵循HTTP协议中定义的内容,在经历了这些之后,我决定更加务实,只把它留给GET和POST。POST方法甚至不需要实现POST- redirect - get模式。

尽管如此,正如我上面提到的,客户端应用程序将是调用服务的应用程序,它只在需要时(不是每次)调用带有所有数据的POST请求。这可以防止对服务器的不断请求。

轮询

尽管REST也可以用于轮询,但我不推荐使用它,除非出于浏览器兼容性的考虑必须使用它。为此,我将使用WebSockets,我也为它设计了API契约。旧浏览器的另一个替代方案是CometD。

其他回答

这里的无状态意味着请求的状态或元数据不在服务器端维护。通过在服务器上维护每个请求或用户的状态,将导致性能瓶颈。服务器只是被请求提供执行任何特定操作所需的属性。

对于会话管理,或者为用户提供自定义体验,需要维护一些元数据或用户状态,可能是用户的偏好,过去的请求历史。这可以通过维护cookie、隐藏属性或进入会话对象来完成。

这可以维护或跟踪用户在应用程序中的状态。

希望这能有所帮助!

REST is stateless and doesn’t maintain any states between the requests. Client cookies / headers are set to maintain the user state like authentication. Say Client username/password are validated by third part authentication mechanism – 2nd level OTP gerneation etc. Once user get authenticated – headers /cookies comes to rest service end point exposed and we can assume user as auth since user is coming with valid headers/cookies. Now certain info of user like IP is either maintained in the cache and after that if request is coming from same Ip (mac address) for listed resources User is allowed. And cache is maintained for some particular time which get invalidated once time lapses. So either cache can be used or DB entries can be used to persist info b/w the requests.

他们只是说不要使用会话/应用程序级数据存储吗?

不。他们不是在用一种无关紧要的方式说。

他们说不要定义“会话”。不登录。不注销。为请求提供凭据。每个请求都是独立的。

您仍然有数据存储。您仍然拥有身份验证和授权。您只是不需要浪费时间建立会话和维护会话状态。

关键在于,每个请求(a)都是完全独立的,(b)可以简单地外包给一个巨大的并行服务器群,而不需要任何实际工作。Apache或Squid可以盲目且成功地传递RESTful请求。

如果我有一个消息队列,而我的用户想要读取消息,但在读取消息时,又想在会话期间阻止某些发送者的消息通过,该怎么办?

如果用户需要一个过滤器,那么只需在每个请求上提供过滤器。

难道……不合理吗?服务器是否只发送未被用户阻止的消息(或消息ID) ?

是的。在RESTful URI请求中提供筛选器。

每次请求新的消息列表时,我真的必须发送整个消息发送者列表来阻止吗?

是的。这个“要阻止的消息发送者列表”可以有多大?一个简短的PK列表?

GET请求可以非常大。如果有必要,您可以尝试POST请求,尽管它听起来像一种查询。

没有勺子。

不要把无状态想象成“一次又一次地把你所有的东西发送到服务器”。不可能。总会有状态——数据库本身也是一种状态,毕竟你是注册用户,所以没有服务器端,任何客户端信息都是无效的。从技术上讲,您从来都不是真正无状态的。

关于登录的争论

不保持会话并每次都登录是什么意思? 有些意思是“每次都发送密码”,这太愚蠢了。有些人说“不,当然不是,而是发送一个令牌”——你瞧,PHP会话就是这么做的。它发送一个会话id,这是一种令牌,它可以帮助你到达你的个人物品,而不必每次都重发u/pw。它也非常可靠,并且经过了良好的测试。是的,方便也会变成缺点,见下一段。

减少碳足迹

What you should do, instead, and what makes real sense, is thin your webserver footprint to the minimum. Languages like PHP make it very easy to just stuff everything in the session storage - but sessions have a price tag. If you have several webservers, they need to share session info, because they share the load too - any of them may have to serve the next request. A shared storage is a must. Server needs to know at least if someone's logged in or not. (And if you bother the database every time you need to decide this, you're practically doomed.) Shared storages need to be a lot faster than the database. This brings the temptation: okay, I have a very fast storage, why not do everything there? - and that's where things go nasty in the other way.

你的意思是,保持会话存储最小?

Again, it's your decision. You can store stuff there for performance reasons (database is almost always slower than Redis), you can store information redundantly, implement your own caching, whatever - just keep in mind that web servers will have a bigger load if you store a lot of rubbish on them. Also, if they break under heavy loads (and they will), you lose valuable information; with the REST way of thinking, all that happens in this case is the client sends the same (!) request again and it gets served this time.

那该怎么做呢?

No one-fits-all solution here. I'd say choose a level of statelessness and go with that. Sessions may be loved by some and hated by others but they're not going anywhere. With every request, send as much information as makes sense, a bit more perhaps; but don't interpret statelessness as not having a session, nor as logging in every time. Somehow the server must know it's you; PHP session ids are one good way, manually generated tokens are another. Think and decide - don't let design trends think for you.

The whole concept is different... You don't need to manage sessions if you are trying to implement RESTFul protocol. In that case it is better to do authentication procedure on every request (whereas there is an extra cost to it in terms of performance - hashing password would be a good example. not a big deal...). If you use sessions - how can you distribute load across multiple servers? I bet RESTFul protocol is meant to eliminate sessions whatsoever - you don't really need them... That's why it is called "stateless". Sessions are only required when you cannot store anything other than Cookie on a client side after a reqest has been made (take old, non Javascript/HTML5-supporting browser as an example). In case of "full-featured" RESTFul client it is usually safe to store base64(login:password) on a client side (in memory) until the applictation is still loaded - the application is used to access to the only host and the cookie cannot be compromised by the third party scripts...

我强烈建议禁用RESTFul服务的cookie认证…检查Basic/Digest Auth -这对于基于rest的服务应该足够了。