2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
松村有倫氏(以下、松村):それでは、「Goでprotocプラグイン作った話」というタイトルで発表します。
自己紹介します。松村有倫と申します。2020年に新卒でDMM.comに入社して、現在はプラットフォーム事業本部の基盤開発グループで働いています。Go歴は1年くらいで、ここ1年間は、Go製プロダクトの保守だったり、プロキシやツールの実装だったりをGoでやってきました。
本日は、運用自動化のためのツールをGoで自作した話をします。「Protocol Buffers」のスキーマ定義からGoのコードを生成するツールです。
それと関連して、GoでGoのコードを生成する時についても少し話せるとよいかなと思っています。よろしくお願いします。
まず、僕が所属している基盤開発グループの紹介からしたいと思います。プラットフォーム事業本部(以下、PF)では、各事業共通で使われる会員基盤だったり、決済基盤だったりをWebAPIで提供していて、僕が所属している基盤開発グループは、それらのAPIの横断処理の部分を担当しています。持ち物のプロダクトとしては、Go製のAPI Gatewayや認可APIなどを持っています。
これ以外にも、PF全体のAPI改善に向けた取り組みも行っていて、最近だと、PF内のDDD推進も行っています。
さて、そんな基盤開発グループですが、最近「API-Gatewayが提供するAPI定義の管理基盤が欲しい」という話が上がってきています。
「APIの追加時にレビューをして、APIの品質を高めていきたい」「管理したデータを活用して各種の自動化みたいなのが行えるとよい」といった部分がモチベーションにつながっています。
そこで、このAPI定義の管理基盤をProtocol BuffersとGitで構築できないか、というプロジェクトを最近は進めています。
「Protocol Buffers」について、少し紹介したいと思います。Protocol Buffersは、Googleが作ったプログラミング言語非依存の通信データのシリアライズフォーマットです。
専用のInterface Definition Language(IDL)で通信スキーマを定義して使うかたちになっています。例えばこんな感じで、「Ping」というサービスがあって、その中にPingというrpcメソッドがあります。リクエストの型がPingReqで、中身の定義は(スライドを示して)こんな感じ。レスポンスはPingRespという型を返して中身は(スライドを示して)こんな感じ。という風に専用のDSLで通信スキーマを定義して使えるものになっています。
今回、API定義の管理フォーマットとしてProtocol Buffersを採用した理由ですが、まず、スキーマ記述言語としてIDLが非常に使いやすかったことが挙げられます。
Protocol BuffersのIDLは部分構造を分けて記述できますし、それ以外でもいろいろと簡素で読みやすいものになっています。あとは、「protoc」というProtocol Buffersのコンパイラによって定義した「スキーマ定義」を幅広く活用できるのも利点の1つだと思います。
すでにスキーマ定義からgRPCを実装したり、ドキュメントを生成したりするツールが世の中にありますし、自分のプラグインで拡張すると、ほかにもさまざまなコード生成が可能になります。
このあたりの特徴から、API定義のフォーマットとして、Protocol Buffersは非常に優秀だと思って、API定義の管理フォーマットとしてProtocol Buffersを採用しました。
今日は「プラグインで拡張すれば、ほかにもさまざまなコード生成が可能」という部分を紹介したいと思います。
例として、「rest-frontend」というAPI-Gateway用のREST/gRPC変換プロキシの話をします。
これが必要になった経緯ですが、API-GatewayとしてRESTのバックエンドとgRPCのバックエンドの両系統をサポートしつつ、一方でクライアントには、共通してRESTで提供する構成を取りたいという話が出てきました。
その過程で、gRPCのバックエンドに対して、RESTとgRPCの変換を行うモジュールとして、API Gatewayの後ろに、rest-frontendという変換プロキシを置くことになりました。
このrest-frontendのコードは、実装に使うコード自体もProtocol Buffersからツールで生成しています。「grpc-gateway」というツールがあって、protobufからサービス定義ごとに、RESTとgRPCの変換を行うプロキシのGo実装を生成してくれます。
コードは、こんな感じになっています。まず、NewServeMuxという関数で、gRPC用のGateway(grpc-gateway用のルータ)の生成を行います。その生成したルーターに対して、ホストを指定してサービスごとにプロキシをマウントしていきます。
例えば、生成のもとになったprotoファイルに「foo」というサービスと「bar」というサービスがある場合、RegisterFooHandlerFromEndpointで、fooのプロキシをマウントして、バックエンドのホストはfoo.example.com。
あとは、barに対して、RegisterBarHandlerFromEndpointという関数でプロキシをマウントして、ホストはbar.example.comみたいに指定します。このように、サービスごとにプロキシをマウントして、最後にhttp.ListenAndServeで、通常のhttp.Handlerとしてlistenすることで、変換プロキシを実装できます。
(スライドを示して)ここですが、grpc-gatewayはそれぞれのサービスごとにgRPCの変換部分のコードを自動生成してくれますが、最後にホストを指定して、ルーターに埋め込む部分は手作業になってしまいます。
このルーティング設定をなんとか自動化できないかと考えました。ホストの設定は、コードに直接埋め込むのではなく、別に管理して注入できるようにしたいという話があったからです。
また、「Gatewayに新規のサービスが追加されるたびに、いちいち作業するのはちょっと面倒くさい」というのもモチベーションだったりします。
今回はprotoファイルの中にサービスの一覧の定義があるので、このルーティング設定の部分も、protocプラグインで自動生成できるのではないかと考えて、プラグインを制作する流れになりました。
ここからは、protocのプラグインの実装について、紹介していきたいと思います。
protocのプラグインの実体ですが、protocと標準入出力で通信する実行形式になっています。この通信フォーマットが、なんとprotobufになっていて、protobufのツールであるprotoc自身にprotobufが使われているという、ちょっとかっこいい作りになっています。
実はプラグインの実装に使える言語は、protobufを解釈できて、実行形式をビルドできるものであれば自由になんでも使えるのですが、今回はGoで実装することにしました。
作りとしては、protocから標準入力経由で、protobuf形式のprotoファイル情報をもらってきます。
それとは別に、プラグインにバックエンドのホスト設定をYAMLの形式で渡して、この2つから情報を抽出して、出力ファイルの情報もprotobuf形式で標準出力に返します。すると、protocがそのレスポンスを標準出力から読み取って、ルーターのコードを生成してくれる流れになります。
使うライブラリですが、Go言語の場合は、google.golang.orgの「protbuf」というモジュールに全部まとまっています。
主に利用するパッケージは3つ。1つ目は「proto」っていうパッケージです。これはprotobufの各種処理をGoから行うためのライブラリです。
2つ目が「types/pluginpb」。これは、protocとプラグインの間の通信に対するメッセージの型を管理するためのパッケージです。
最後が「types/descriptorpb」。protocから渡されてくるprotoファイルの情報を記述するためのメッセージ型を管理するための定義が入ったパッケージです。
(次回へつづく)
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略