如何在REST中管理状态

use*_*050 32 rest session-state

我想这个问题听起来很熟悉,但我还是另一个被REST困惑的程序员.

我有一个传统的Web应用程序,从StateA到StateB等等.如果用户去了StateB的(URL),我想确保他之前访问过StateA.传统上,我使用会话状态执行此操作.

由于REST中不允许会话状态,我该如何实现?

KP *_*lor 50

这有两个REST答案,具体取决于您要做的具体操作.

如果您真的想要管理基于请求的状态(例如当用户正在通过多屏幕向导或其他一些基于导航的工作流程时),那么REST的答案是该状态应该来回发送每个请求/响应(使用隐藏文本字段,查询字符串或存储在表单中的POST数据).这是Martin Fowler的"客户状态"设计模式的实现(在他的书"企业应用程序架构模式 "中详细介绍;请参阅此处以供参考).

另一方面,如果您尝试在服务器上管理某种新对象(例如购物车),那么REST的答案是您实际上正在创建一个可以像任何其他方式一样访问的新实体.直接网址.是否将此新实体存储在数据库或应用程序内存中(如传统的Session对象)取决于您,但无论如何,新对象不是关于服务器上的"状态",而是关于创建新实体的更多信息.用户与之交互的实体.

  • 还有一点.如果您采用"服务器上的新对象"方法,则应将其视为第一类资源,并且应具有标识URL. (5认同)
  • @Darrel\Miller我认为教条式REST也需要多页向导的URL.启动向导将创建一个新资源,为每个页面创建一个新资源,每个资源的响应包括一个"下一个"链接.你可以施加一个约束,即必须在"最终资源"之前创建所有"页面资源"; 这可以隐式地完成,使用像"1/2/3/submit"这样的URL.这看起来有点傻,因为它正在重新创建会话状态,只是使用URL.一个优点是,如果URL是永久链接,则会话无法超时.您可以将其加入书签以便稍后完成. (4认同)
  • 有趣的观点."state"(要转发和退回)和"resource"(要分配URI)之间的边界线在哪里?它是关于"具体性"的,就像"一堆导航信息是一种状态,但看起来更像是一个实体或容器或对象的东西是一种资源"?还是更多关于生命的时间?还是范围? (4认同)
  • @ChristianGosch似乎区分这两者(对我来说,无论如何)的一件事是会话持久性.也就是说,如果客户失败(或退出),失去什么是可以接受的?丢失的将处于应用程序状态.如果客户端出现故障(或注销),您希望保留的任何内容都必须存储在资源中.亚马逊的购物车就是一个例子. (4认同)