今天我们发布了Connect,一个用于构建浏览器和gRPC兼容的HTTP API的纤细框架。Connect是为生产准备的--专注、简单、可调试--并且它与gRPC客户端和服务器完全兼容。如果你对今天的gRPC库的复杂性和不稳定性感到沮丧,我们认为你会发现Connect是一股新鲜空气。**Connect-go现在可以在Apache 2开源许可下使用,文档可以在connect.build**上找到。我们将很快发布Connect for TypeScript,更多的语言将陆续发布。
另一个RPC框架?
在其发布后的七年里,gRPC为Protobuf RPC带来了亟需的共识。从一个相互竞争、互不兼容的业余项目开始,gRPC团队将社区团结在一个共同的协议周围,向许多开发者介绍了RPC风格的API,并推动了Protobuf在谷歌之外的普及。由于他们的不懈努力,我们可以用Protobuf指定我们的API,用gRPC实现它们,并确信大多数语言都会有一个兼容的客户端库。
从概念上讲,gRPC协议是带有Protobuf编码的体的HTTP,并洒上了元数据。尽管有这个简单的前提,但该协议和今天的gRPC库都有一个最大限度的设计理念,导致了非凡的复杂性。gRPC非但没有使生产系统变得简单和稳定,反而使开发、部署、调试和维护过度复杂化。
作为一个例子,考虑谷歌在Go中的gRPC实现。
- 除去注释,
grpc-go是13万行手写的代码。它有几十个子包,近百个配置选项,以及定制的名称解析和负载平衡机制。仅仅筛选这些功能的厨房水槽就需要几个小时,而且代码的数量之大使得细微的错误和资源泄漏不可避免。 grpc-go没有使用Go标准库的net/http,而是使用自己的HTTP/2实现。它与Go的HTTP生态系统的其他部分不兼容,所以你不能干净地将gRPC请求与其他HTTP流量一起提供,也不能使用大多数第三方包。- gRPC协议需要对HTTP/2和拖车的端到端支持。支持常见的HTTP客户端--如网络浏览器--需要精心设计的翻译代理。
- 除了使用晦涩的HTTP特性外,gRPC协议还很难调试。即使启用了JSON支持,简单的请求-响应RPC也会将你关心的JSON与二进制框架数据混合在一起。忘了
curl | jq或Chrome网络检查器吧--现有的工具都是不成熟的,而且是针对gRPC的。 - 作为一项政策,
grpc-go,不遵循语义版本;发布说明甚至包括一个专门的 "行为变化 "部分。在过去的一年中,至少有四个版本破坏了向后的兼容性,著名的gRPC用户(包括etcd)往往在几个月内都无法更新。
平衡grpc-go"的开源社区和谷歌内部用户的需求是一项困难和不容易的任务。而且,也许它的功能和选项的广度是谷歌内部需要采用的。对于我们其他人来说,grpc-go 的复杂性和不稳定性代表了我们核心业务的不愉快的分心。
生产级的简单性
Connect为Protobuf驱动的API带来了简单性。每一个Connect的实现都是集中的:只有基本的功能,建立在经过时间考验的HTTP库之上,并被设计为不影响你的工作。
-
在Go中,Connect只是一个包,只有几千行代码和少数几个常用的选项。即使是生成的代码也是为了让人阅读。
-
它是建立在
net/http。Connect处理程序实现了http.Handler,而Connect客户端则包裹了http.Client。它们与任何第三方路由器、中间件或服务器一起工作。 -
在
net/http的基础上,connect-go支持三种RPC协议:gRPC、gRPC-Web和Connect自己的协议。处理程序默认支持这三种协议,而客户端可以通过一个配置选项来切换协议--不需要改变其他代码。 -
连接协议是一个简单的、仅有POST的协议,通过HTTP/1.1或HTTP/2工作。它吸收了gRPC和gRPC-Web的最佳部分,包括流媒体,并将其打包成一个协议,在浏览器、单体和微服务中同样适用。Connect协议是我们认为gRPC协议应该有的样子。默认情况下,支持JSON-和二进制编码的Protobuf。调用Connect API就像使用
curl一样简单。# Try it out! This is a live demo! curl \ --header "Content-Type: application/json" \ --data '{"sentence": "I feel happy."}' \ https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say -
connect-go也支持完整的gRPC协议,包括流媒体、头文件、拖车和错误细节。gRPC兼容的服务器反射和健康检查可以作为独立的软件包使用。代替cURL,我们可以用以下方式调用我们的Connect API[grpcurl](https://github.com/fullstorydev/grpcurl):# This is also a live demo! go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest grpcurl \ -d '{"sentence": "I feel happy."}' \ demo.connect.build:443 \ buf.connect.demo.eliza.v1.ElizaService/Say -
处理程序和客户端也支持gRPC-Web协议,因此浏览器可以直接连接到你的服务器。我们使用谷歌自己的互操作性测试的扩展版本来验证我们的gRPC和gRPC-Web实现。
-
头文件、预告片和其他元数据都是明确传递的,而不需要将任何东西附加到Go上下文中。通过泛型,所产生的代码是符合人体工程学的,类型安全的,并且易于推理。
如果你使用过Buf CLI或Schema Registry,你就使用过Connect - 在内部,我们已经用connect-go 完全取代了grpc-go 。我们发现Connect在生产中是一种乐趣:它很小,很简单,而且可以调试。
在Go中,Connect目前处于测试阶段:我们在生产中依靠它,但我们可能会在收集早期采用者的反馈时做一些改变。我们计划在十月给稳定的v1.0 ,在Go 1.19发布后不久。我们非常重视语义上的版本管理:一旦我们发布v1.0 ,我们就不会破坏你的构建。
即将发布
我们对Connect生态系统有很大的计划!除了Go中的Connect,我们一直在为浏览器开发TypeScript的实现。它具有相同的设计优先级:它一路都是成语式的TypeScript,接近浏览器的获取API,整齐地适合React钩子,并支持gRPC-Web和Connect自己的协议。它还能产生微小的捆绑。我们已经在Buf Schema Registry前端替换了grpc-web ,并且我们计划很快发布connect-web ,敬请关注。
最终,我们希望为Express、Rails、Django、Laravel和类似的框架发布Connect的实现。你不应该在这些富有成效的工具包和协议缓冲器之间做出选择--它们应该无缝地结合起来。
请参与进来
我们很想听听你对Connect的看法:看看入门指南,在你的下一个Go项目中尝试Connect,探究一下示范项目,如果有什么地方不符合你的期望,请提出问题。我们在Buf Slack中随时待命,而且我们通常也在Gophers Slack的#grpc和#connect频道中。