Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
【encraft#2】Protobufスキーマによる明確なAPI定義
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
hiro
April 25, 2023
Programming
1.1k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
【encraft#2】Protobufスキーマによる明確なAPI定義
hiro
April 25, 2023
More Decks by hiro
See All by hiro
Go1.20 リリースパーティ 統合テストのカバレッジ計測
parsely1231
0
590
Other Decks in Programming
See All in Programming
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
170
AIエージェント時代のコードレビューを設計する
nogu66
6
2.7k
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
1
150
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
240
What We Talk About When We Talk About XP
m_seki
2
630
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.2k
App Intentsのビルドプロセスを支える技術
kntkymt
0
380
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
330
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
1.9k
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
120
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
400
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
700
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Speed Design
sergeychernyshev
33
2.1k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
The agentic SEO stack - context over prompts
schlessera
0
940
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
410
First, design no harm
axbom
PRO
2
1.3k
Transcript
~コミュニケーションを支える技術~ Protobufスキーマによる明確なAPI定義 Encraft #2 サーバーとクライアントを結ぶ技術 2023/04/25(Tue) @IT_parsely / 樋口 陽介(hiro)
© Know ledge Work Inc. 自己紹介 樋口 陽介(hiro) @IT_parsely •
株式会社ナレッジワーク • バックエンドエンジニア • 今年のテーマの一つは「がんばって登壇してみる」 ◦ Go1.20リリースパーティ ◦ つきなみGo ◦ Go Conferenceは落ちました
© Know ledge Work Inc. • backendとfrontendを型安全に連携できる • シンプルにスキーマが書ける •
自動生成の文化があり、周辺ツールがそろっている • RESTで開発できる(ESPでHTTP↔️gRPC変換) 3 protobuf採用の背景
© Know ledge Work Inc. 4 セッション概要 コミュニケーションツールとしてのprotobuf .protoファイルを起点としてどのように開発しているか 話すこと
データ通信に関すること 話さないこと protobuf駆動の開発例をもとに嬉しさ・辛さを知ってもらう 今日のゴール
© Know ledge Work Inc. • protobuf駆動の開発紹介 ◦ Frontend ◦
Backend • 権限管理の拡張 • エラーハンドリング • 今後検討したいこと 5 Agenda
© Know ledge Work Inc. protobuf駆動の開発紹介
© Know ledge Work Inc. 7 protobuf駆動の開発 全体像 DesignDoc API定義(protobuf)
DesignDocでAPI定義を含む 全体設計についてやりとり protobuf から自動生成された インタフェースを基準に実装 開発の最初に .protoを作成 backend 今日のトピック frontend
© Know ledge Work Inc. 8 protobuf駆動で開発をすすめるにあたって 自然とprotobuf駆動になるような仕組み作り .protoファイルの利便性・重要性を高める とにかく型安全に
自動生成を最大限に活かす 重要な情報は.protoファイルに明示
© Know ledge Work Inc. 型定義の生成はts-protoを採用 EnumはTypeScriptのstring unionで出力できるように実装 をOSS Contribute
--ts_proto_opt=enumsAsLiterals=true https://github.com/stephenh/ts-proto/pull/450 @otofu-square 9 protobuf駆動の開発 Frontend message DividerData { enum DividerType { DOUBLE = 0; SINGLE = 1; DASHED = 2; DOTTED = 3; } DividerType type = 1; } export const DividerData_DividerType = { DOUBLE: 'DOUBLE', SINGLE: 'SINGLE', DASHED: 'DASHED', DOTTED: 'DOTTED', UNRECOGNIZED: 'UNRECOGNIZED', } as const; export type DividerData_DividerType = typeof DividerData_DividerType[keyof typeof DividerData_DividerType]; 型の強みを最大限活かす
© Know ledge Work Inc. google.api.httpオプションでREST対応 REST通信用のAPI Clientを自作pluginで生成 10 protobuf駆動の開発
Frontend async getUser(req: GetUserRequest): Promise<{ data: GetUserResponse, resHeaders: { [key: string]: string }, }> { const response = await requester.request( "GET", "user", "/v1/users/$id", "application/json", GetUserRequest.toJSON(req) as{ [key: string]: string | string[] }, "", ) if (response.ok) { return { data: GetUserResponse.fromJSON(awaitresponse.json()), resHeaders: headersToMap(response.headers), } } RESTの通信部分は自動生成 service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse) { option (google.api.http) = {get: "/v1/users/{id}"}; } }
© Know ledge Work Inc. 基本的なコード群はprotocで生成 ServiceのImplementsを自作pluginで生成 Service共通の処理 認証処理(詳細後述) 11
protobuf駆動の開発 Backend type UserServiceServer interface { GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) } func (s *userServiceServer) GetUser( ctx context.Context, req *appservice.GetUserRequest, ) (*appservice.GetUserResponse, error) { userID, err := idtype.UserIDFromString(req.Id) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid user id (%s)", req.Id) } a, err := s.authorizer.Authorize( ctx, userID, roleactionmodel.UsersGet.ID, ) if err != nil { return nil, err } return s.getUser(ctx, a, req) } Serverの共通処理を自動生成
© Know ledge Work Inc. protoファイルの変更を検知 CIで自動生成を実行してPR作成 12 protobuf駆動の開発 CI
コード生成も自動化
© Know ledge Work Inc. 13 小括(protobuf駆動の開発紹介) 開発者間のAPIに関する認識ずれ API変更時のフィールド修正漏れなど、 単純な実装ミスに対するレビューのやり
とり 実現する状態 明確なAPI定義による共通認識 単純な実装ミスは型の力をかりてコンパイ ル時に検出でレビューコスト低減 よくある課題
© Know ledge Work Inc. 権限管理の拡張
© Know ledge Work Inc. 認証処理を自動生成することで実装ミスによるセキュリティインシデントを防ぐ 15 権限仕様をprotoで明示する嬉しさ Frontend、Backend間でAPI実行権限に共通認識を持ち、不具合を減らす セキュアな実装
API実行権限の共通認識
© Know ledge Work Inc. 16 具体的な方法 service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse) { option (google.api.http) = { get: "/v1/users/{id}" }; option (kw.auth_options) = { auth_type: AUTH_TYPE_USER action_name: "users.get" }; } } protobufのメソッド定義に認証用のオプション を追加 リソースとアクションを明示 extensionsによる拡張
© Know ledge Work Inc. 17 Backendでの活用 func (s *userServiceServer)
GetUser( ctx context.Context, req *appservice.GetUserRequest, ) (*appservice.GetUserResponse, error) { userID, err := idtype.UserIDFromString(req.Id) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid user id (%s)", req.Id) } a, err := s.authorizer.AuthorizeUserRole( ctx, userID, roleactionmodel.UsersGet.ID, ) if err != nil { return nil, err } return s.getUser(ctx, a, req) } 認証処理を行うpublicメソッドを自動生成 開発者は認証以降の処理を実装する 認証処理の自動生成
© Know ledge Work Inc. 18 Frontendでの活用 権限に合わせたUIの出し分けに活用 ユーザーに権限のあるaction一覧をserverから取得 protobufの情報と合わせてAPIの実行権限を確認
API実行権限とUI
© Know ledge Work Inc. 19 小括(権限管理の拡張) 詳しい人に聞かないとAPIの実行権限が わからない 実現する状態
protoファイルをみるだけで実行権限が わかる protoに明示された権限情報を参照して UIをコントロールできる よくある課題
© Know ledge Work Inc. エラーハンドリング
© Know ledge Work Inc. 特定のエラーが起きた時にユーザーに復旧方法をフィードバックしたい エラー情報のやりとりも型安全に行いたい 21 エラーハンドリングの背景 エラーのフィードバック
gRPCのカスタムエラーの辛み type Status struct { Code int32 `json:"code,omitempty"` Message string `json:"message,omitempty"` Details []*anypb.Any `json:"details,omitempty"` } Detailsに任意のmessage型を詰め込む仕様 型安全にエラーを連携するのが難しい
© Know ledge Work Inc. 22 カスタムエラーのハンドリング エラー用の型を定義して、型安全に通信できる Detailsの中身をエラー用のmessage型にパースするコード を自作pluginで生成
import type { AppServiceError } from './appservice_error_type' import { ServiceLinkageError, } from './appservice_error'; export const parseAppServiceErrorBody = (body: { details?: any[] }): AppServiceError[] => { const { details } = body if (!details || !Array.isArray(details)) { return [] } return details.map(parseAppServiceError).filter((error): error is AppServiceError => !!error) } 型安全なエラーのやり取り message ServiceLinkageError { ServiceLinkageErrorType type = 1; string service_name = 2; google.protobuf.StringValue cause_detail = 3; }
© Know ledge Work Inc. 23 小括(エラーハンドリング) 実現する状態 どんなエラーが返ってくるかわからない エラーハンドリングが煩雑
エラーの型も明確に定義されている エラーレスポンスも正常系と同じように パースできる よくある課題
© Know ledge Work Inc. 24 エラーハンドリングでできていないこと • APIごとにどのようなエラーを返すのかprotoに明示 •
Serverからエラーを返す時に、Detailsに含めるmessage型を制限
© Know ledge Work Inc. 今後検討したいこと
© Know ledge Work Inc. 26 今後検討したいこと • protoc-gen-validateの導入 •
より型安全なエラーハンドリング • gRPC-Web
None