
- 記事作成日:2022/12/01
情報
| 名前 | URL |
|---|---|
| Github | https://github.com/bufbuild/connect-go |
| 公式サイト | https://connect.build/docs/introduction |
| デモサイト | https://connect.build/ |
| 開発母体 | Buf |
| version | 1.3.0 |
| 言語 | Go |
| 価格 | 無料 |
| ライセンス | Apache-2.0 license |
何ができるもの?
Go で gRPC / gRPC-web / connect(独自プロトコル) が簡単に使えるライブラリ
使い方
❯ mkdir connect-go-example ❯ cd connect-go-example ❯ go mod init example ❯ go install github.com/bufbuild/buf/cmd/buf@latest ❯ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest ❯ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest ❯ go install github.com/bufbuild/connect-go/cmd/protoc-gen-connect-go@latest
❯ mkdir -p greet/v1
❯ touch greet/v1/greet.proto
❯ cat << EOF > greet/v1/greet.proto
heredoc> syntax = "proto3";
package greet.v1;
option go_package = "example/gen/greet/v1;greetv1";
message GreetRequest {
string name = 1;
}
message GreetResponse {
string greeting = 1;
}
service GreetService {
rpc Greet(GreetRequest) returns (GreetResponse) {}
}
heredoc> EOF
❯ cat << EOF > buf.gen.yaml
version: v1
plugins:
- name: go
out: gen
opt: paths=source_relative
- name: connect-go
out: gen
opt: paths=source_relative
EOF
❯ buf lint
❯ buf generate
.
├── buf.gen.yaml
├── gen
│ └── greet
│ └── v1
│ ├── greet.pb.go
│ └── greetv1connect
│ └── greet.connect.go
├── go.mod
└── greet
└── v1
└── greet.proto
greet.pb.go: protoc-gen-go による proto 定義を Go コードにしたものgreet.connect.go: protoc-gen-connect-go による proto 定義を HTTP Handler にしたもの
サーバ実装コードの追加
❯ cat << EOF > cmd/server/main.go
heredoc> >....
"log"
"net/http"
"github.com/bufbuild/connect-go"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
greetv1 "example/gen/greet/v1" // generated by protoc-gen-go
"example/gen/greet/v1/greetv1connect" // generated by protoc-gen-connect-go
)
type GreetServer struct{}
func (s *GreetServer) Greet(
ctx context.Context,
req *connect.Request[greetv1.GreetRequest],
) (*connect.Response[greetv1.GreetResponse], error) {
log.Println("Request headers: ", req.Header())
res := connect.NewResponse(&greetv1.GreetResponse{
Greeting: fmt.Sprintf("Hello, %s!", req.Msg.Name),
})
res.Header().Set("Greet-Version", "v1")
return res, nil
}
func main() {
greeter := &GreetServer{}
mux := http.NewServeMux()
path, handler := greetv1connect.NewGreetServiceHandler(greeter)
mux.Handle(path, handler)
http.ListenAndServe(
"localhost:8080",
// Use h2c so we can serve HTTP/2 without TLS.
h2c.NewHandler(mux, &http2.Server{}),
)
}
heredoc> EOF
確認
❯ curl --header "Content-Type: application/json" --data '{"name": "Jane"}' http://localhost:8081/greet.v1.GreetService/Greet
{"greeting":"Hello, Jane!"}
利用シーン
- Go で grpc をつかいたけど、grpc-go は見通し悪いなあという時。
- シンプルにやりたい時
登場背景
by DeepL
gRPC は、その発表以来 7 年間に渡り、Protobuf RPC に待望のコンセンサスをもたらしてきました。競合する、相互に互換性のない趣味のプロジェクトのスープから出発して、gRPC チームは、共通のプロトコルの周りにコミュニティを結集し、多くの開発者に RPC スタイルの API を紹介し、Google 以外の Protobuf の人気を牽引してきました。彼らのたゆまぬ努力のおかげで、私たちは Protobuf で API を指定し、gRPC で実装し、ほとんどの言語が互換性のあるクライアント ライブラリを持っていると確信できるようになりました。
概念的には、gRPC プロトコルは HTTPに Protobuf でエンコードされたボディとメタデータを追加したものです。この単純な前提にもかかわらず、このプロトコルと今日の gRPC ライブラリは、非常に複雑化した最大公約数的な設計理念を共有しています。gRPC は、生産システムをシンプルで安定したものにするのではなく、開発、配備、デバッグ、保守を過度に複雑にしています。
例として、GoogleのgRPCのGoでの実装を考えてみましょう。
コメントを除くと、grpc-goは13万行の手書きのコードです。何十ものサブパッケージがあり、100近い設定オプションがあり、特注の名前解決とロードバランシングメカニズムがあります。また、膨大な量のコードがあるため、微妙なバグや リソースリークも避けられません。Go標準ライブラリのnet/httpを使用するのではなく、grpc-goはHTTP/2の独自の実装を使用します。これは Go の HTTP エコシステムの残りの部分と互換性がないので、他の HTTP トラフィックと一緒に gRPC リクエストをきれいに提供することができず、ほとんどのサードパーティ パッケージを使用することができません。
gRPCプロトコルはHTTP/2やTrailerをエンドツーエンドでサポートする必要があり、Webブラウザのような一般的なHTTPクライアントをサポートするには、精巧な翻訳プロキシが必要です。不明瞭な HTTP 機能を使用することに加え、gRPC プロトコルはデバッグが困難です。JSON サポートを有効にしても、単純なリクエストとレスポンスの RPC は、気になる JSON とバイナリー・フレームデータを混在させます。curl | jqや Chrome のネットワーク インスペクタを忘れてください - 利用可能なツールはすべて未熟で gRPC 固有のものです。
ポリシーとして、grpc-goはセマンティックバージョニングに従いません。リリースノートには、"動作の変更 "のための特別なセクションさえ含まれています。過去 1 年間に少なくとも 4 回のリリースで後方互換性が破られ、(etcd を含む)著名な gRPC ユーザは、しばしば一度に数ヶ月間アップデートすることができない状況にあります。
grpc-goのオープンソースコミュニティとGoogleの内部ユーザのニーズのバランスをとることは難しく、ありがたい仕事です。そして、おそらくその幅広い機能とオプションは、Google社内で採用されるために必要なものでしょう。しかし、それ以外のユーザーにとっては、grpc-goの複雑さと不安定さは、我々のコアビジネスから目をそらす不快なものでしかないのです。
気にすること
- 利用者数と開発者数にだいぶ開きがあるので connect を使う場合はそれなりの覚悟が必要。
- ただコード量も少なく見通しも良いので、そんなに困ることは少なそう。(HTTP/2の実装がないのがいい)
- まだ対応している言語が少ない