自从Roy Fielding于2000年在他的博士论文中提出REST(REpresentational State Transfer)的概念之后,REST就迅速流行起来。REST之所以流行,主要原因在于REST是基于已经广为人知的HTTP协议。数据交换格式直接使用XML或JSON,传输直接使用HTTP/1.1,数据加密直接使用SSL/TLS,一切都是现有的流行的技术。当然REST清晰简单的架构风格,也是它流行的原因之一。
很多人有一个误区,认为只要是基于HTTP的API都是RESTful API。这是不正确的。RESTful API一个重要的特征是对Resource的各种操作,Resource由URI标示,而操作则是标准的HTTP Method,比如GET、POST、PUT、DELETE等。例如下面的两个例子,前一个是RESTful API,后一个则不是:
GET http://www.example.com/student/25
gRPC则是google于2015年开源的一个RPC框架。它是基于protoBuf和HTTP/2实现的。google的官方文档声称gRPC是语言中立、平台中立的RPC框架,但其实REST也是语言中立、平台中立的。
因为gRPC是基于protoBuf,所以数据传输是二进制格式,而REST一般采用XML或JSON,所以是text格式。因此对于数据序列化、反序列化,gRPC效率更高,性能自然更好。但是理论上REST也可以采用protoBuf格式,这里只是说的一般情况,因为目前一提到REST,基本就是HTTP/1.1 + JSON。从另一个角度来看,XML或JSON是human-readable,所以更便于调试。
gRPC相比REST具有更高的性能的另一个原因是采用了HTTP/2。HTTP/2的多路复用、server端主动push等功能使gRPC增色不少。当然,REST也可以采用HTTP/2,而且HTTP/2兼容HTTP/1.1。
前文已提到RESTful API是围绕resource的各种标准的HTTP操作,而对于gRPC,则可以定义任意API。因为gRPC采用了protoBuf,所以定义消息和接口就非常简单,gRPC官网给出了一个例子如下:
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
用protoc编译之后,就可以自动生成相应语言的目标代码,既包含服务器端的接口,也包含客户端的接口。对于服务器端来说,只需要实现服务器端的接口即可;对于客户端来说,直接调用生成的客户端接口即可。其它所有的一切,gRPC都替你搞定了。对于客户端来说,仿佛调用本地函数,对于服务端,仿佛接收到一个来自本地的调用。
注:protoBuf包含protoBuf Compiler和protoBuf Runtime两部分。具体请参考:
https://github.com/google/protobuf
所以gRPC简化了开发过程。而且用REST和gRPC实现同样的功能,gRPC需要开发的代码量会少很多,至少当你使用gRPC时,你不需要自己decode/encode请求消息或响应消息,因为这些事情gRPC都默默替你做了。
由于gRPC会同时生成服务端和客户端的接口,所以服务端和客户端紧紧地耦合在一起,因此服务端和客户端需要同时更新,具有相同的开发周期。而对于REST来说,客户端和服务端则具有低耦合性,可以分开维护。
没有任何一种技术或框架可以包治百病,目前来看,gRPC完全替换REST不太可能。如果对于性能极度敏感,那么gRPC是更好的选择;如果看重项目的长期可维护性、扩展性,REST则更适合。
限于作者水平和精力,欢迎留言进行纠正和补充!
--END--
领取专属 10元无门槛券
私享最新 技术干货