前言
这两天在和同学谈到RPC、RESTful时候发现自己对这两者并不是很理解,于是查阅了网上相关资料加上自己的理解写下本篇文章以加深印象,由于本人水平有限,若对这两者的理解有不妥之处望指出。
什么是REST和RESTful
在认识RESTful之前,我们先科普一下REST。
REST
REST即Representational State Transfer的缩写,是基于HTTP协议之上的一组约束和属性,翻译过来是表现层状态转移。REST是一种设计风格(并非一种标准),描述的是在网络中Client和Server的一种交互形式,目的是便于不同的软件/程序在网络中互相传递消息。按照我的理解:我们通过URI定位到服务器上的资源(例如文本、图片、服务),然后对资源进行某种操作(CRUD)并且返回足够的信息描述服务器的状态(比如:状态码)让客户端知道如何处理,资源传递给客户端并且以某种形式表现(比如JSON、HTML、XML、PNG等)出来,而REST则是将URI的命名风格、对资源操作的实现方式、操作之后返回什么信息和资源以哪种形式表现出来等总结成了一种设计风格,让大家都使用这种设计风格去实现这些设计,当然REST的设计风格不止我指出的这几个,只是这几个是要点。 REST设计的风格遵循以下几点:
- 利用HTTP方法让接口统一化 REST充分利用HTTP自身的GET、POST、PUT、DELETE的方法实现接口的统一化,比如对同一个资源进行CRUD操作时:
GET /posts 获取文章 GET /getPosts 获取文章
POST /posts 发布文章 GET /addPosts 发布文章
PUT /posts 修改文章 GET /editPosts 修改文章
DELETE /posts 删除文章 GET /deletePosts 删除文章
复制代码
上面的设计中,左边的是符合REST设计风格的,右边的是不符合REST设计风格的。URI只需将资源准确无误的暴露出来就可以,而不需要加上动作词,而动作则体现在HTTP的GET、POST、PUT、DELETE方法中,其中URI还推荐使用复数。
- 利用HTTP状态码返回状态信息 下面举例几个HTTP Status Code和表示的什么:
Status Code: 200 OK
Status Code: 400 Bed Request
Status Code: 404 Not Found
Status Code: 500 Internal Server Error
复制代码
其中2XX的状态码表示请求已成功被服务器已接收、理解、并接受 3XX的状态码表示重定向 4XX的状态码表示客户端错误 5XX的状态码表示服务器错误
- 利用HTTP报头告知对方如何处理本次请求(相应) HTTP报头是描述客户端与服务器之间的请求或者响应应该如何处理本次请求的,比如该用什么表现形式。
Authorization 认证报头
Cache-Control 缓存报头
Cnotent-Type 消息体类型报头
复制代码
- 无状态 REST设计风格要求Server无状态,无状态并不等于不保存用户的状态,而是指服务器不保存请求状态(会话信息),客户端必须每次都带上自己的状态去请求服务器,如果确实要维持用户的状态,也应由客户端负责,例如:在服务端上通过Cookie保存Token,之后的请求中都带上Token,而这个Token就保存有了用户的状态(如登录信息)。这里需要注意的是:
- 通过Session保存状态不是REST设计风格,因为Session是将状态信息(用户信息、过期时间等)保存在了服务器上,比如用户登录成功后,会将Session信息保存在服务器,然后返回个SessionID给客户端并且将SessionID保存在Cookies中,之后的请求客户端都会通过Cookies传递SessionID给服务器,服务器根据客户端传来的SessionID去匹配之前保存的Session状态信息,所以这个状态是保存在服务器上的,是靠服务器维持的,所以不是REST设计风格。
- 通过Token保存状态是REST设计风格,因为状态信息(用户信息、过期时间等)都是保存在Token中,而Token又是保存在客户端中(如Cookies),比如用户登录成功后,服务器会返回一个Token(包含了用户信息、过期时间等)给服务端,服务端将Token保存在Cookies中,之后的请求客户端都会取出Token放到Request Headers中传给服务器,服务器验证Token的有效性即可。
看到这里是不是能理解**状态转移*这个词了?就是状态通过客户端来转移。
简单的来说就是状态信息保存在服务器的就是有状态的,而状态信息保存在客户端的就是无状态的。通过REST的无状态原则恰好有利于实现负载均衡,在分布式的Web系统上,有多个可用的服务器,每个服务器都可以处理客户端发来的请求,及时有一台服务器宕机,无状态的请求可以交给别的服务器处理,这是有状态的请求所做不到的。
什么是RESTful
理解完REST那我们就很容易理解RESTful了,RESTful即实现REST设计风格的一种架构,如RESTful API(REST设计风格的API)
什么是RPC
RPC就是Remote Procedure Call的简称,翻译成中文就是远程过程调用,什么是远程过程调用?举个例子:有两台服务器A、B,一个应用部署在A服务器上,另一个应用部署在B服务器上,A服务器上的应用想要调用B服务器上应用所提供的方法、函数,那么这个调用过程就需要网络来支撑,整个调用过程可以用下图表示。
RPC分类
其中RPC分为两种:
- 同步调用 在上面举的例子中,A服务器的应用调用B服务器上应用的方法、函数后,A服务器的应用会处在阻塞状态,只有等到B服务器上的应用通过网络返回结果后,A服务器的应用才会继续往下执行。
- 异步调用 在上面举的例子中,A服务器的应用调用B服务器上应用的方法、函数后,A服务器的应用并不会进入阻塞状态等待结果的返回,可以通过回调通知等方式获得返回的结果。
RPC的网络通信问题
我们知道在RPC调用的时候需要网络来支撑,那么以何种方式来实现通信呢。
- HTTP协议 A服务器的应用可以通过HTTP将数据传输到B服务器,B服务器接收到数据后执行数据中调用的指定方法、函数,例如谷歌的gRPC就是在HTTP上进行数据传输的。但是由于HTTP报头中有太多不需要的信息造成带宽的浪费,所以很多人都是用比HTTP传输效率高的TCP、UDP进行数据传输。
- TCP、UDP 例如著名的Netty就是基于TCP、UDP上进行传输的,当然你也可以不使用框架,自己编写Socket实现网络数据传输。
RESTful API和RPC
RESTful API和RPC区别和关系
在我理解中,RESTful API和RPC是两种完全不同概念的东西,是没法放在一起比较的,如果硬要将它俩比较,我认为RESTful是RPC的一种实现,即RPC包括RESTful API,但RPC不等于RESTful API。
- RPC:我认为RPC是一种为实现远程调用而提出一种思想,至于你用什么方式去达到目的都可以(例如:用什么网络协议来传输数据看自己的选择)。
- RESTful API:符合REST设计风格的一种接口架构,它也是通过网络进行的远程调用,但是远程调用仅限于HTTP。
RESTful API和RPC用途
既然RESTful API和RPC都可以实现远程调用,那我们应该在这两者之中如何抉择呢?
- RESTful API:主要用在为第三方提供调用自家系统的一种途径。
- RPC:主要用在自家系统之间的互相调用,即实现系统的分布式。
总结
在这里我仅是以我掌握的知识给大家介绍RPC和RESTful,给初学者大概了解一下RPC和RESTful,若文中有不妥的地方希望大家指出。