Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
カーナベルにおけるProtobuf二次利用例
Search
andoshin11
February 23, 2025
Technology
0
90
カーナベルにおけるProtobuf二次利用例
カーナベルでProtobufの運用とコード生成を使い倒しているPlatform Engineeringの事例を紹介します
andoshin11
February 23, 2025
Tweet
Share
More Decks by andoshin11
See All by andoshin11
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」Microservices認証認可基盤
andoshin11
0
560
カーナベル株式会社2024年2月 エンジニアイベント資料
andoshin11
0
310
Private Cloudを支える最高のユーザーガイド運用技術
andoshin11
0
290
TS CompilerがVueを喋れても良いじゃないか
andoshin11
0
720
ain't giving up type-safe Express
andoshin11
2
430
Type Safe "Everything"
andoshin11
0
240
Hack your Nuxt router!
andoshin11
0
1.3k
GatewayパターンとSchema駆動開発
andoshin11
7
1.4k
Catch up Nuxt.js 2019.02
andoshin11
0
2.1k
Other Decks in Technology
See All in Technology
Making a MIDI controller device with PicoRuby/R2P2 (RubyKaigi 2025 LT)
risgk
1
280
生成AIによるCloud Native基盤構築の可能性と実践的ガードレールの敷設について
nwiizo
7
1k
AI Agentを「期待通り」に動かすために:設計アプローチの模索と現在地
kworkdev
PRO
2
460
アセスメントで紐解く、10Xのデータマネジメントの軌跡
10xinc
1
440
意思決定を支える検索体験を目指してやってきたこと
hinatades
PRO
0
210
Amazon CloudWatch を使って NW 監視を行うには
o11yfes2023
0
170
PostgreSQL Log File Mastery: Optimizing Database Performance Through Advanced Log Analysis
shiviyer007
PRO
0
100
AWSの新機能検証をやる時こそ、Amazon Qでプロンプトエンジニアリングを駆使しよう
duelist2020jp
1
260
Road to Go Gem #rubykaigi
sue445
0
870
ガバクラのAWS長期継続割引 ~次の4/1に慌てないために~
hamijay_cloud
1
280
バクラクの認証基盤の成長と現在地 / bakuraku-authn-platform
convto
2
630
AI AgentOps LT大会(2025/04/16) Algomatic伊藤発表資料
kosukeito
0
140
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
2.9k
Agile that works and the tools we love
rasmusluckow
328
21k
Embracing the Ebb and Flow
colly
85
4.6k
Gamification - CAS2011
davidbonilla
81
5.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Six Lessons from altMBA
skipperchong
27
3.7k
Automating Front-end Workflow
addyosmani
1369
200k
4 Signs Your Business is Dying
shpigford
183
22k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Adopting Sorbet at Scale
ufuk
76
9.3k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
Transcript
カーナベルにおけるProtobuf 二次利用事例 2025/02/23 カーナベル社内勉強会 @andoshin11
今日話すこと 1. スキーマ駆動開発のおさらい + Protobuf運用の現状確認 2. ProtobufからJSON Schema validatorを生成した苦労話 3.
E2E Coverage計測のためのOSSを開発した話
スキーマ駆動開発の おさらい
分散システムとスキーマ駆動開発 • カーナベルのRepositories構成 ◦ Frontend ▪ selling-web, profile-web, admin-frontend ◦
Backend ▪ Inventory Service, Authority Service, TCG Service, etc… ◦ Infrastructure ▪ ka-nabell-terraform, tcg-platform-manifests ◦ Schema ▪ tcg-platform-proto
分散システムとスキーマ駆動開発 • カーナベルのRepositories構成 ◦ Frontend ▪ selling-web, profile-web, admin-frontend ◦
Backend ▪ Inventory Service, Authority Service, TCG Service, etc… ◦ Infrastructure ▪ ka-nabell-terraform, tcg-platform-manifests ◦ Schema ▪ tcg-platform-proto API Schemaを独立したRepositoryに 切り出しているのが特徴 ↓ システム間の契約としてのスキーマの Ownershipをアプリケーションから切り離す
分散システムとスキーマ駆動開発 ◦ 古典的なAPI運用 ▪ Server > Clientという一方通行の主従関係 ▪ Backend依存の同期的な開発工程 ▪
自然言語で記述された「API定義書」の保守
分散システムとスキーマ駆動開発 ◦ モダンなスキーマ駆動開発 ▪ スキーマ = システム間の契約 ▪ スキーマさえ定義されていればBackend, Frontendともに非同期
な開発進行が可能に ▪ 標準記法によるmachine readableなスキーマ定義 • Protocol Buffer, Open API, GraphQL, etc… ▪ 各種言語向けのServer & Clientコードを自動生成可能 • → 仕様と実装が一致する ▪ テストコードやUtilityツールも自動生成可能
分散システムとスキーマ駆動開発 ◦ モダンなスキーマ駆動開発 ▪ スキーマ = システム間の契約 ▪ スキーマさえ定義されていればBackend, Frontendともに非同期
な開発進行が可能に ▪ 標準記法によるmachine readableなスキーマ定義 • Protocol Buffer, Open API, GraphQL, etc… ▪ 各種言語向けのServer & Clientコードを自動生成可能 • → 仕様と実装が一致する ▪ テストコードやUtilityツールも自動生成可能 Protocol Bufferで定義された API Schemaを使い倒す
Protocol Bufferの二次利用 ◦ API定義としてのProtobufからコード自動生成して二次利用する ◦ 現在自動生成しているもの ▪ APIドキュメント(protoc-gen-doc) ▪ TypeScript向けの型定義(ts-proto)
▪ Nest.js Server向けのMethod Handler(ts-proto) ▪ gRPC-Web向けのClientコード(protoc-gen-grpc-web) ▪ Request & Response型のJSON Schema(typescript-json-schema) ▪ ECMASCript向けのJSON Schema Validator(ajv) ◦ その他の二次利用 ▪ API認可スコープの定義(Speaker Deck) ▪ E2Eテストのカバレッジ計測(proto-coverage-reporter)
Protocol Bufferの二次利用 ◦ API定義としてのProtobufからコード自動生成して二次利用する ◦ 現在自動生成しているもの ▪ APIドキュメント(protoc-gen-doc) ▪ TypeScript向けの型定義(ts-proto)
▪ Nest.js Server向けのMethod Handler(ts-proto) ▪ gRPC-Web向けのClientコード(protoc-gen-grpc-web) ▪ Request & Response型のJSON Schema(typescript-json-schema) ▪ ECMASCript向けのJSON Schema Validator(ajv) ◦ その他の二次利用 ▪ API認可スコープの定義(Speaker Deck) ▪ E2Eテストのカバレッジ計測(proto-coverage-reporter) 今日はこの辺の話をします
JSON Schema Validatorの生成
型安全性の静的検証と動的検証 ◦ 「変数Aが〇〇型であること」をシステム横断で担保するのは難しい ▪ TSの型定義では〇〇型が入っているがDBには△△型で入ってる ▪ Client schemaとServer schemaのバージョン違いによる齟齬 ▪
ネットワーク境界やBrowser Storageを跨ぐ際のSerialize & Desirializeによる型互換性の消失 ▪ etc… ◦ TS CompilerやPrisma Schemaによる静的型チェックだけでは担保に 限界がある ◦ 特にBackend Serverに対して悪意のあるデータが混入するとシステム 障害やデータ汚染につながるリスクもある
型安全性の静的検証と動的検証 ◦ やりたきこと: ▪ ネットワーク境界を跨いでBackend Serverに到達するリクエス トをランタイムで厳密に検証したい • 型チェック •
必須プロパティのチェック • 不要プロパティの排除 • etc… ▪ Clientに返却するデータもランタイムチェックを行ってあげたい
市中のソリューション ◦ protovalidate ▪ Protoエコシステムのリーダーであるbuf社のツール ▪ Go, C++, Java, Pythonには対応しているがTS対応はなし
▪ 1ヶ月ほど前にようやくTS対応スタート(issue #67) ▪ 今年前半にアルファリリース予定 ◦ protoc-gen-jsonschema ▪ 記憶が曖昧だが、調査時点(2023年1月)で我々のプロジェクトで は利用できない問題があった ▪ メンテも止まっており現在はarchive済み
市中のソリューション ◦ protovalidate ▪ Protoエコシステムのリーダーであるbuf社のツール ▪ Go, C++, Java, Pythonには対応しているがTS対応はなし
▪ 1ヶ月ほど前にようやくTS対応スタート(issue #67) ▪ 今年前半にアルファリリース予定 ◦ protoc-gen-jsonschema ▪ 記憶が曖昧だが、調査時点(2023年1月)で我々のプロジェクトで は利用できない問題があった ▪ メンテも止まっており現在はarchive済み 自前のJSON Schema Validatorを生成しよう
JSON Schema 任意のデータ型の構造定義 + 検証に利用できる標準仕様 json-schema.org
Protobuf → JSON Schemaの生成 ◦ 直接JSON Schemaを生成できるツールはない(前述) ◦ TypeScript interfaceからJSON
Schemaを生成するツールはある (typescript-json-schema) ◦ Protobuf → TypeScript(ts-proto) → JSON Schemaという多段変換 ならいけそう!!
Protobuf → TS → JSON Schema
typescript-json-schemaの落とし穴 ◦ デフォルトのvalidation制約がイマイチ・・・ ▪ string型: 空文字も許容されてしまう ▪ array型: 空配列が許容されない ▪
etc… ◦ → そのままでは弊社のユースケースに適合しない
typescript-json-schemaの落とし穴 ◦ annotationsを付与することで制約を変更できるらしい
typescript-json-schemaの落とし穴 ◦ annotationsを付与することで制約を変更できるらしい ts-protoの生成したTSファイルを 事前加工する必要がある
TypeScript Compiler API ◦ TSファイルを型レベルで解析・加工できる公式API ◦ 内部的にはTSファイルを文字列ではなくAST(抽象構文木)として扱う のが特徴 ◦ Reference:
Using the Compiler API
TypeScript AST Viewerで遊んでみよう Link
TS interfaceにannotationを付与する ◦ typescript-json-schema向けに下記のルールでannotationを付与する ◦ string型 → reqreuid stringなら「@minLength 1」をcomment挿入
◦ array型 → required arrayなら「@minItems 0」をcomment挿入
TS interfaceにannotationを付与する ASTを再帰関数で走査(トラバース)してcommentsを付与
TS interfaceにannotationを付与する 加工したASTをファイル文字列に復元するprinterで出力
JSON Schema Validatorへの変換 ◦ typescript-json-schemaでTS → JSON Schemaに変換 ◦ ajvでJSON
SchemaからECMAScript向けのvalidatorを生成 ▪ Node.js界隈ではデファクトのツール ▪ 複数のvalidation戦略 ▪ JIT(Just in Time) Compile • validation実行時にJSON schemaを読み込みにいき validation関数を内部生成する方式 ▪ AOT(Ahead of Time) Compile • 事前に各JSON Schemaに対応したvalidation関数をビルド し、関数exportする方式 • カーナベルではこちらを利用
まとめ ◦ 安全なBackend Server実装のために値を動的検査できるランタイム validatorが欲しい ◦ エコシステムが貧弱なので自前でProto → TS →
JSON Schema → JSON Schema Validatorへ変換する仕組みが必要 ◦ ライブラリ制約でTS生成後にCompiler APIを用いたファイル加工が必 要 ◦ ajvはAOT Compileしたstandaloneなvalidation関数を生成
まとめ ◦ 安全なBackend Server実装のために値を動的検査できるランタイム validatorが欲しい ◦ エコシステムが貧弱なので自前でProto → TS →
JSON Schema → JSON Schema Validatorへ変換する仕組みが必要 ◦ ライブラリ制約でTS生成後にCompiler APIを用いたファイル加工が必 要 ◦ ajvはAOT Compileしたstandaloneなvalidation関数を生成 ◦ → めっちゃしんどいのでprotovalidateの登場を待ち侘びています
E2E Coverage計測 への取り組み
課題: • システムの肥大化によるAPIエンドポイントの増加 ◦ Customer Service → 25 APIs ◦
Inventory Service → 37 APIs ◦ Selling Service → 41 APIs ◦ TCG Service → 186 APIs(!?) ◦ And more… • デグレを避けるために自動テストの継続実行は必須 • テスト品質を定量的に観測・評価できる仕組みが欲しい
作ったもの proto-coverage-reporter
作ったもの proto-coverage-reporter どのAPIのテストが不十分なのか、 全体で何%のテスト記述が完了 したのか、が追えるのが嬉しい
内部実装の話 • 主に3つの機能で構成されている ◦ テスト結果記録機能 ◦ カバレッジ解析機能 ◦ レポーティング機能
内部実装の話: テスト結果記録機能 • 各テストシナリオにおいてどのAPIのどのStatusがテストされたのかを記録 する必要がある • 各シナリオにおけるリクエスト実行の数は不定 • gRPC Client向けのInterceptorを提供し、全てのAPI通信結果をログとし
て保存する
内部実装の話: テスト結果記録機能
内部実装の話: テスト結果記録機能 • 各テストシナリオにおいてどのAPIのどのStatusがテストされたのかを記録 する必要がある • 各シナリオにおけるリクエスト実行の数は不定 • gRPC Client向けのInterceptorを提供し、全てのAPI通信結果をログとし
て保存する • こだわりポイント: ◦ 各OS準拠のsystem temp directoryにログを格納するようにした ◦ 環境変数によるログディレクトリの指定も可能
内部実装の話: カバレッジ解析機能 • カバレッジ比率計測の母数となる各Method仕様をProtobufから解析 • Protobufには専用のextensionを用いてMethod Optionsを記述する
内部実装の話: カバレッジ解析機能
内部実装の話: カバレッジ解析機能 • こだわりポイント: ◦ extensionを定義したprotobufはPublic Repositoryにホスト ▪ → 外部からもアクセス可能
◦ 現在はstatus_codesのみ対応しているがより複雑なOptionも記述可能 ◦ ex: ignore rules, validation rules, etc…
内部実装の話: レポーティング機能 • Jestのcustom reporter APIを利用してレポーティング機能を実装 ◦ テストコンテキストの参照やLifecycle Hookを活用したテスト終了後 のログクリーンアップ等も可能
• cli-tableとchalkを利用した見やすいレポート出力 • こだわりポイント: ◦ octokitを利用してGitHub Actionsで実行された際はPull Requestに 結果をレポーティングするようにした ◦ すでにレポートコメントがある場合は都度更新を行うロジックを実装
Thank you!