我知道要创建无状态应用程序,我们需要来回传输用户状态而不是服务器保持用户状态。
但是,必须在服务器中存储一些状态,我读这个article,存储在服务器中的状态称为资源状态。所以如果我是对的,我们经常调用的客户端状态应该是相同的作为申请状态。
那么,我如何区分这两者,因为它将决定它们是应该存储在服务器中还是已经传输。
以购物车为例。
如果在用户完成购买之前有5个步骤,则用户所在的阶段(#3,#4)似乎是应用程序状态,但这是否意味着如果他们关闭浏览器并且点击再次付款,他将不得不从step1开始?
他图表中的项目怎么样?如果我们将其视为应用程序状态,我们需要将所有项目放在请求中。但是如果我们这样做,当用户关闭浏览器并再次登录时,他将无法再次找到他的项目,因为浏览器无法记住所有项目。因此,我们似乎应该将其视为资源状态。但如果是这样,当用户点击付费时,他们会有一个不同的页面:根据他的购物车是否为空,去支付或说“你的购物车是空的”。因此,具有完全相同的param输入的相同请求出现了不同的结果,我们仍然可以说它是无状态的吗?
也许我明白了什么不对,请问任何人可以回答如何区分不同类型的状态以及如何区别对待它们?
答案 0 :(得分:6)
资源状态是一种状态,即使在客户端断开连接/重新启动/会话结束/之后也需要持久且可存活。 应用程序状态应该存在于客户端上,并且应该随每个客户端请求提供(如果我们正在谈论REST架构并计划很好地扩展我们的应用程序)。
如何区分应用程序状态和资源状态?
这取决于您正在处理的任务。例如。如果你想弄清楚在你的画廊中当前可以看到的图片的索引保存位置,你可以在你的应用程序状态下进行,因为你可能不需要这个状态来生存这个客户的下一个会话。当然,您可以将它保存在资源状态(数据库)中,但这会产生开销(为获得非常小的收益而付出很多努力)。
但是,如果您正在处理多步骤购买流程,可能最好在资源状态(数据库)中保存此流程的状态,因为您希望永久保存此状态。否则,您的客户需要在断开/重启/等等之后重新填充大量信息。 当然,您可以在cookie中执行此操作(并且它将是应用程序状态),并且此状态可以在浏览器重新启动后生效。但它有两个缺点:1)此状态在其他用户的设备上不可用,2)如果您正在创建真正的REST服务,cookie会使客户的生活变得复杂,因为并非所有客户端都能很好地运行cookie(除了浏览器)。
答案 1 :(得分:1)
我想引用一下RESTful Web Services一书中的一段:
Flickr 网络服务可让您将图片上传到您的帐户,并存储这些图片 服务器。让客户端发送每一张图片都会很疯狂 每个请求flickr.com,只是为了防止服务器存储任何状态
应用程序状态与客户端执行某些操作可以遵循的路径相关。 例如,在查阅文章时,会出现“添加到购物车”链接。咨询购物车时,如果您的购物车中有一篇文章,则会提供“支付订单”链接,否则此链接不会显示。根据他所遵循的链接,随意让用户创建自己的应用程序状态。基本上,应用程序状态是 context 的问题。
在我回到你的例子之前提到的同一本书的另一个引用:
资源状态保留在服务器上并且是 仅以表示形式发送给客户。应用程序状态保持在 客户端,直到它可用于创建,修改或删除资源。然后它被发送到 服务器作为POST,PUT或DELETE请求的一部分,并成为资源状态。
因此,假设您有一些身份验证机制(基于令牌)。并且一个用户帐户与一个购物车相关联。
当您在购物车中添加商品时,您正在修改购物车资源。由于资源状态是服务器端,因此它位于服务器上
假设您断开连接,并重新连接,如第一点所述。购物车还在这里。
只要客户端在每个请求中发送不同的身份验证凭据,您的应用程序就会保持无状态。
关于如何管理它的SO的一个很好的讨论:Do sessions really violate RESTfulness?
现在,以下事实:咨询您的购物车可以引导您采取两种不同的行动,具体取决于是否有物品。
很简单。服务器向客户端提供的服务取决于服务器维护的资源状态
关于this good website的一个非常简单的例子。您可以看到,根据帐户的金额,服务器会提供指向客户的链接以进行撤销。
请随意(再次)制作自己的应用程序并关注链接。
我建议你看一下HATEOAS和解释它的Richardson Maturity Model。 顺便说一下,这两个段落的引用来自同一作者的这个模型。