+
95
-

API开发用gRPC还是GraphQL?

API开发用gRPC还是GraphQL?


网友回复

+
15
-

gRPC是由Google开发的一个高性能、通用的开源RPC框架,主要面向移动应用开发且基于HTTP/2协议标准而设计,同时支持大多数流行的编程语言。

GraphQL既是一种用于API的查询语言,且GraphQL对API中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让API更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

两者看起来并用途不相同,但其实在通信场景中很多开发者面临如何选择的问题。

gRPC是由谷歌在2016年发布的,它是一种高效且对开发者友好的服务器间通信协议。GraphQL是由Meta公司在2015年发布的,是一种高效的、对开发者友好的客户端-服务器通信协议。两者都比REST有明显的优势,并且有很多共同点。 我们将文章中花大量的篇幅比较它们的特点,然后总结每个协议的优点和缺点。最后,我们会描述每种协议都适合哪些特定的领域,以及什么时候会出现跨领域使用不同协议。

比较gRPC和GraphQL的功能

1.界面设计

gRPC和GraphQL都是界面描述语言(IDL),描述了两台计算机如何进行通信。它们适用于不同的编程语言,我们可以使用codegen工具来生成多种语言的类型化接口。IDL抽象出了传输层;GraphQL与传输无关,但通常工作在HTTP之上,而gRPC则工作在HTTP/2之上。我们不需要知道传输层的细节,比如REST中的方法、路径、查询参数和正文格式。我们只需要知道针对一个独立的节点,如何使用高级客户端库与之通信。

2.信息格式

gRPC使用协议缓冲区(又称protobufs),这是一种二进制格式,只包括数值(传递的内容),而GraphQL使用JSON,它是基于文本的,除了数值外还包括字段名(数值的含义)。二进制格式与较少的信息发送相结合,通常导致gRPC消息比GraphQL消息小。(虽然高效的二进制格式在GraphQL中是可行的,但它很少被使用,也不被大多数的库和工具所支持)。 影响消息大小的另一个方面是overfetching(过度获取):我们决定是否只请求特定的字段或总是接收所有的字段(通过避免"overfetching"过滤掉我们不需要的字段,只接受我们需要的字段)。因此,对于GraphQL而言利用了overfetching技术可以在请求中指定需要哪些字段,而在gRPC中,我们可以使用FieldMasks作为请求的可重用的过滤器,该过滤器和overfetching有异曲同工之妙。 gRPC使用二进制格式的另一个好处是,比GraphQL信息的序列化和解析更快。当然,缺点也很明显,它比JSON而言更难查看和调试,毕竟JSON的信息结构更加适合人类阅读。在Temporal项目中(开源微服务平台),我们默认使用protobuf的JSON格式,以利于开发者体验的可见性。(这失去了二进制格式带来的效率,但更看重效率的用户可以切换到二进制)。

3.默认值

gRPC不在消息中包括默认值,而GraphQL可以对参数进行默认值的设置,但不能对请求字段或响应类型进行默认值设置。这导致gRPC消息尺寸较小的另一个因素。它还影响了消费gRPCAPI的DX,在不设置输入字段和将该字段设置为默认值没有什么区别,默认值也是基于字段类型的值。我们不能把`behavior`枚举输入字段默认为`BEHAVIOR_FOO=2`--我们必须把默认值放在第一位(`BEHAVIOR_FOO=0`),这意味着它在总是默认值,或者我们遵循推荐的做法,定义一个`BEHAVIOR_UNSPECIFIED=0`枚举值。 enumBehavior{ behavior_unspecified=0。 behavior_foo=1; behavior_bar=2;

}1.2.3.4.5.

API提供者需要传达UNSPECIFIED的意思(通过记录"unspecified将使用默认行为,目前是FOO"),消费者需要考虑服务器的默认行为在未来是否会改变(如果服务器在消费者正在创建的业务实体中保存了UNSPECIFIED/0值,而服务器后来改变了默认行为,那么该实体将会有所不同),以及这种改变是否是所期望的。如果并不希望如此,客户需要将该值设置为当前的默认值。 这种方式比gRPC版本更简单,这种方式可以知道如果不提供字段会发生什么,而且我们不需要考虑是否要自己传递默认值。 其他类型的默认值也有一些特殊情况。对于数字而言,有时默认的0是一个有效的值,而有时它将意味着一个不同的默认值。对于布尔型,默认的false会导致字段被负数命名。当我们在编码时给布尔变量命名时,我们使用正向命名。例如,我们通常会声明letretryable=true而不是letnnotallow=false。人们通常认为前者更易读,因为后者需要额外的步骤来理解双重否定("notRetryable是假的,所以它是可重试的")。但是如果我们有一个gRPCAPI,我们希望默认...

点击查看剩余70%

我知道答案,我要回答