🌀

ConnectのgRPC相互運用性テストから得た学び

2022/12/04に公開

この記事は Go Advent Calendar 2022 4日目の記事です。

2022年6月にgRPCを拡張したプロトコルである Connect とそのGo実装が発表され、GoやgRPCを使っている開発者の中で話題になりました。

ConnectのGo実装である connect-go は gRPCのGo実装である grpc-go と相互運用が可能になっています。つまり、今クライアントやサーバーにgrpc-goを使っているアプリケーションがある場合、それをconnect-goに置き換えることができるということです。もちろん、ただライブラリを差し替えるだけでなくコードの部分的な修正は必要になりますが、サーバーはgrpc-goで動かしたままクライアントはconnect-goに移行するというようにクライアントとサーバーを独立して移行することができるわけです。

クライアントで利用される grpc-web についても connect-web が相互運用可能となっています。gRPC-Webといえばサーバーサイドではgrpc-goなどを利用し前段にEnvoyなどをリバースプロキシとして利用するのが一般的ですが、サーバー側でconnect-goを使う場合Envoyはそのまま使い続けることもできますし、取り除くこともできるという柔軟性があります。

このようにconnect-goやconnect-webは既存のgRPCの実装と相互運用することを意識して実装されています。そしてその相互運用性テストを行っているリポジトリが connect-crosstest です。このリポジトリではgRPC公式の相互運用性テストのテストケースを利用しつつ、grpc-goとconnect-goというように各実装をまたいだテストを含めて相互運用性テストが行われています。こちらはDocker Composeを使ってローカルでテストを実行することができます。

https://github.com/bufbuild/connect-crosstest/blob/main/Makefile#L110-L113

*_test.go のような形式でテストが行われているわけではないため、一見何をやっているのかわかりづらいですがMakefileの dockercomposetestgodockercomposetestweb を見ることで大まかにどのようなパターンのテストを行っているのか雰囲気をつかめると思います。

プロダクションでgrpc-goからconnect-go(もしくはgrpc-webからconnect-web)に切り替える場合は、いくら相互運用性が保たれているとはいえ実際に各エンドポイントが正常に動作するかどうか検証をすることになるかと思います。connect-crosstestでは検証をサーバーサイドで行うのではなく、クライアントサイドでデコードした結果を利用している部分が検証でコードを書く際に参考になりそうなポイントだと感じました[1]。Goのクライアントの場合は proto#Equal という関数が検証のために利用されていて、これも使えそうです。

gRPC-Webの実装では公式の他に有名なものとして improbable-eng/grpc-web があります。connect-crosstestをForkしてこちらも含めた相互運用性テストをしてみるというのも面白い試みかもしれません。

2023年はプロダクションでConnectを採用したというような事例も増えていくのではないかと思っています。gRPCまわりのエコシステムはまだまだ伸びしろがあり、今後の進化が楽しみです。

脚注
  1. サーバーサイドで検証している例: https://shopify.engineering/how-shopify-reduced-storefront-response-times-rewrite ↩︎

Discussion