
2025.03.19
ドバイ不動産投資の最前線 専門家が語る、3つの投資モデルと市場の展望
リンクをコピー
記事をブックマーク
松村有倫氏(以下、松村):それでは、「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ファイルの情報を記述するためのメッセージ型を管理するための定義が入ったパッケージです。
(次回へつづく)
2025.03.21
マネージャーの「自分でやったほうが早い」という行動で失うもの 効率・スピード重視の職場に足りていない考え方
2025.03.17
不確実な時代だからこそ「知らないこと」を武器にする ハーバード主席卒業生の逆説的なメッセージ
2025.03.17
いくら読書をしても「成長しない人」が見落としていること 10分でできる「正しい学び方」
2025.03.17
ソフトバンクとOpenAIにとって「歴史的な日」になった 孫正義氏が語る、AI革命の全ぼう
2025.03.19
部下の「タスクの先延ばし」が少ない上司の特徴とは? 研究が示す、先延ばし行動を減らすリーダーの条件
2025.03.18
フェデラー氏が語る「努力しない成功は神話」という真実 ダートマス卒業生に贈る勝利の秘訣
2025.03.18
全知全能の最先端AI「Cristal」が企業の大脳となる ソフトバンク孫正義氏が語る、現代における「超知性」の可能性
2025.03.19
フェデラー氏が語る「ただの1ポイント」の哲学 ウィンブルドン敗北から学んだ失敗からの立ち直り方
2025.03.18
部下に「そうかなぁ?」と思われない1on1の問いかけ エンゲージメントを高めるマネジメントに欠かせない「聴く」技術
2025.03.19
組織をダメにする“害虫”の正体は間違った思い込み AIやDXなど手段のみにこだわるダメ上司の見極め方
2025.03.21
マネージャーの「自分でやったほうが早い」という行動で失うもの 効率・スピード重視の職場に足りていない考え方
2025.03.17
不確実な時代だからこそ「知らないこと」を武器にする ハーバード主席卒業生の逆説的なメッセージ
2025.03.17
いくら読書をしても「成長しない人」が見落としていること 10分でできる「正しい学び方」
2025.03.17
ソフトバンクとOpenAIにとって「歴史的な日」になった 孫正義氏が語る、AI革命の全ぼう
2025.03.19
部下の「タスクの先延ばし」が少ない上司の特徴とは? 研究が示す、先延ばし行動を減らすリーダーの条件
2025.03.18
フェデラー氏が語る「努力しない成功は神話」という真実 ダートマス卒業生に贈る勝利の秘訣
2025.03.18
全知全能の最先端AI「Cristal」が企業の大脳となる ソフトバンク孫正義氏が語る、現代における「超知性」の可能性
2025.03.19
フェデラー氏が語る「ただの1ポイント」の哲学 ウィンブルドン敗北から学んだ失敗からの立ち直り方
2025.03.18
部下に「そうかなぁ?」と思われない1on1の問いかけ エンゲージメントを高めるマネジメントに欠かせない「聴く」技術
2025.03.19
組織をダメにする“害虫”の正体は間違った思い込み AIやDXなど手段のみにこだわるダメ上司の見極め方
【手放すTALK LIVE#046】 出版記念イベント 『大きなシステムと小さなファンタジー』 一つ一つのいのちが大切にされる社会へ
2025.02.03 - 2025.02.03
「聴く」から始まる組織変革 〜篠田真貴子さんと考える対話型マネジメント〜
2025.02.14 - 2025.02.14
「目の前の利益を優先する」心理とは:ビジネスに活かせる意思決定の科学
2025.02.12 - 2025.02.12
新刊『組織をダメにするのは誰か?職場の問題解決入門』出版記念セミナー
2025.02.04 - 2025.02.04
会社の体質、これまでどおりで大丈夫? 職場に新たな風を吹き込むための「ネガティブ・ケイパビリティ」入門
2025.02.10 - 2025.02.10