我正在使用Angular2前端开发一个相当复杂的Web应用程序。我想维护与基于Node.js的RESTful API的所有客户端 - 服务器通信,这些API将JSON对象传入和传出。
但是,我对REST应该是无状态的要求感到有些困惑。在服务器端存储或生成了大量数据,并将其存储在客户端并将其附加到每个请求都会产生相当大的开销。
例如:有数百个与某个用户相关的权限(即,可以在什么级别访问哪些资源)。客户端未加密承载这些权限是一个明显的安全问题;每次请求重新提交所有数据(加密)都会感觉很奇怪。在每次请求时从数据库中刷新它们都会影响性能。
我的意思是,当然至少在身份验证时生成的某种访问令牌必须在每次请求时传递给服务器。我只是假设我生成了一个不可猜测的会话ID(仅在成功的auth时),并以http-only(限制JavaScript访问),安全(强制执行https-only)cookie并使用此cookie传递给客户端在服务器端保持一些节俭的会话状态(如权限)。但似乎这种做法在REST世界中是不受欢迎的?是一个有状态的RESTful API是矛盾的,异端吗?
答案 0 :(得分:3)
但是,我对REST应该是无状态的要求感到有些困惑
如有疑问,请查看论文 - 在这种情况下,Fielding非常清楚 stateless 的含义:
通信本质上必须是无状态的......这样,从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。因此,会话状态完全保留在客户端上。
换句话说,没有代词。他描述了描述Client-Stateless-Server architecture
时的主要好处这些约束改善了可见性,可靠性和可伸缩性。可见性得到改善,因为监控系统不必超出单个请求数据,以确定请求的完整性质。可靠性得到改善,因为它简化了从部分故障中恢复的任务。可扩展性得到改善,因为不必在请求之间存储状态允许服务器组件快速释放资源并进一步简化实现。
客户端无状态服务器的缺点是它可能通过增加在一系列请求中发送的重复数据(每个交互开销)来降低网络性能,因为该数据不能在共享上下文中留在服务器上。
我们不假设服务器托管纯功能; 当然服务器端有状态。在大多数情况下,拥有REST api的目的是提供一个接口,以适应Web的服务器端状态(以任何形式)。
例如:有数百个与某个用户相关的权限(即,可以在什么级别访问哪些资源)。客户端未加密承载这些权限是一个明显的安全问题;每次请求重新提交所有数据(加密)都会感觉很奇怪。在每次请求时从数据库中刷新它们都会影响性能。
服务器缓存一些自己的状态并没有根本性的错误,作为在后续调用的情况下改善响应时间的优化。这一切都隐藏在界面背后,根本不影响REST约束。 (如果下一个请求被路由到另一个服务器,您将获得缓存未命中和第二次查找,但那些不会以任何方式更改请求的含义。)
但是服务器不应该对客户端状态做出任何假设,因为它无法看到正在发生的事情;客户端状态可以在不通知服务器的情况下进行更改(后退按钮,请求由中间组件处理,请求由同一服务器的其他副本管理)。
另一方面,客户端确切地知道客户端在发送任何给定消息时的状态;它管理会话。任何相关的会话数据都会被客户端复制到请求中,服务器会对请求内容及其自身状态进行操作,而不会有任何先前请求的内存。