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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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コードの読む量は減らせる / designing-for-code-reading
minodriven
34
16k
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2k
R8 の設定見直しでアプリサイズ削減
andpad
0
190
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
120
JRuby: Past, Present, and Future
headius
0
230
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.9k
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.5k
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
210
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
190
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
680
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
140
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
200
Featured
See All Featured
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
Designing for Timeless Needs
cassininazir
1
520
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
420
The Language of Interfaces
destraynor
162
27k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
610
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
Practical Orchestrator
shlominoach
192
12k
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