无状态与否,REST服务的形式与设计内涵
最早我自己学习了IT黑马的瑞吉外卖项目时,我对REST服务的理解是片面的。在这个项目中,REST仅仅是作为前后端通信的手段. 我对于REST服务的理解只是局限在形式上,即它仅仅是一种规范,通过指定不同的HTTP请求方式、使用JSON响应等方式来实现前后端通信。但我一直没有很好地理解( 根本不知道)其中一个重要的设计理念——无状态。
直到最近在学习了Spring实战第六版中的使用Oauth2保护REST服务的章节后,我对REST服务的设计理念有了更深的理解,特别是无状态的理解。
无状态指的是服务端不保存任何客户端信息,它只根据请求信息来判断客户端的身份和要执行的意图。
在瑞吉外卖项目中,每个请求都需要进行登录验证,并将当前用户信息保存到服务器中,这是一种有状态的处理方式。无论是将信息保存到session中还是使用threadlocal,实质上都是在服务器端存储用户信息,以便根据这些信息处理请求。
相比之下,无状态的REST服务中,用户信息并不在服务器中进行维护,而是直接记录在JWT token中,REST服务可以通过简单的验证就可以识别出请求的用户身份。这样,REST服务就专注于处理业务逻辑,而不需要负担用户信息的维护,这种设计就让REST服务更加高效和灵活。 同时使得REST服务可以更好地进行水平扩展,因为它不需要维护用户信息,所以可以很方便地进行集群部署。
总结
使用SpringMVC的RestController注解仅仅是配置注册的控制器响应请求时将返回结果 转为json在响应体中返回,但这一步并不是完成REST服务的真正步骤。 因为并未改变服务端状态,仍需保存用户信息。这只完成REST服务的形式,而未完全实现REST服务的设计思想。
使用Oauth2规范,可以很好地实现无状态的REST服务,但这并不是唯一的方式。无状态的REST服务的设计思想是:服务端不保存任何客户端信息,它只根据请求信息来判断客户端的身份和要执行的意图。 例如,在一个restapi的方法中,(最好情况下) 我不需要根据serverContext才能处理这个请求,而是所有我需要的context都已经在request中体现了。这样,当进行集群化等手段进行水平扩展时就不需要担心它的上下文环境。