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
gRPCミドルウェアを作ってみよう
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Shintaro Kanno
August 03, 2022
Programming
650
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
gRPCミドルウェアを作ってみよう
Shintaro Kanno
August 03, 2022
More Decks by Shintaro Kanno
See All by Shintaro Kanno
アトミックデザイン入門
shintaro8
0
330
Goの並行処理に入門しよう
shintaro8
0
160
Azure Functionsを使ってSlackに通知をしてみよう
shintaro8
0
600
Other Decks in Programming
See All in Programming
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
590
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
500
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
430
ChromeでローカルLLM
ryu1013
0
140
JIS keyboard support in Omarchy
lef237
0
110
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
610
最近”作らせてる” ローカルAIアプリの話
akit37
0
470
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
410
sbt 2.0: takeoff
eed3si9n
0
160
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
890
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
How to train your dragon (web standard)
notwaldorf
96
6.9k
How Software Deployment tools have changed in the past 20 years
geshan
2
35k
Everyday Curiosity
cassininazir
0
350
A Tale of Four Properties
chriscoyier
163
24k
Abbi's Birthday
coloredviolet
4
10k
Rails Girls Zürich Keynote
gr2m
96
14k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
480
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
410
The browser strikes back
jonoalderson
0
1.8k
Transcript
gRPCミドルウェアを作ってみよう
名前 : 官野 慎太朗 業務 : 都内のIT事業会社にて勤務 技術経験: - JavaScript/TypeScript,
Go - MySQL, PostgreSQL - Docker, Kubernetes - Azure, Aws - Git, RestfulAPI, gRPC, etc… @shinshin8 @doctorkanno572
gRPCのミドルウェアを使ったこ とはありますか? ?
go-grpc-middleware(github.com/grpc-ecosystem/go-grpc-middleware) • gRPC開発に必要なインターセプ ター、ヘルパー、ユーティリティなどを 提供 • 認証、ロギング、リカバリ、リトライなど の機能を実現
提供されている以外の機能が欲しい・・・
! 自前でgRPCミドルウェアを 作ってみよう
1. 4つのRPCについて 2. Unary Server Interceptorの基本構造 3. Google Maps APIを使ったgRPCミドルウェアの実装
Agenda
1. 4つのRPCについて
• Unary RPC ◦ クライアントからの1つのリクエストに対し、サーバーが1つのレスポンスをクライアントに返す。 • Server streaming RPC ◦
クライアントからの1つのリクエストに対し、サーバーが複数のレスポンスをクライアントに返す。 • Client streaming RPC ◦ クライアントからの複数のリクエストに対し、サーバーが1つのレスポンスをクライアントに返す。 • Bidirectional RPC ◦ 通信が確立後、クライアントとサーバー間で任意のタイミングでのやりとりを行う。
1. 2. Unary Server Interceptor の基本構造
Unary Server Interceptorの基本的な構成 func UnaryInterceptor() grpc.UnaryServerInterceptor { return func (
ctx context.Context, req interface {}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } }
Unary Server Interceptorの基本的な構成 func UnaryInterceptor() grpc.UnaryServerInterceptor { return func (
ctx context.Context, req interface {}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } } • grpc.UnaryServerInterceptor ◦ ミドルウェアの戻り値 ◦ 戻り値で関数を返す
4つのパラメータ func UnaryInterceptor() grpc.UnaryServerInterceptor { return func ( ctx context.Context,
← ★ req interface {}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } } • ctx : コンテキスト
4つのパラメータ func UnaryInterceptor() grpc.UnaryServerInterceptor { return func ( ctx context.Context,
req interface {}, ← ★ info *grpc.UnaryServerInfo, handler grpc.UnaryHandler ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } } • ctx : コンテキスト • req : クライアントから受け取 るリクエスト
4つのパラメータ func UnaryInterceptor() grpc.UnaryServerInterceptor { return func ( ctx context.Context,
req interface {}, info *grpc.UnaryServerInfo, ← ★ handler grpc.UnaryHandler ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } } • ctx : コンテキスト • req : クライアントから受け取 るリクエスト • info : サーバー情報
4つのパラメータ func UnaryInterceptor() grpc.UnaryServerInterceptor { return func ( ctx context.Context,
req interface {}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler ← ★ ) ( resp interface {}, err error ) { // ~~~ implementation ~~~~ return handler(ctx, req) } } • ctx : コンテキスト • req : クライアントから受け取 るリクエスト • info : サーバー情報 • handler : 後続の処理
意識したい処理の流れ func ( ~~~~~~~~~ ) ( ~~~~~~~~~ ) { //
ミドルウェアで行いたい処理を実装 return handler(ctx, req) } 処理結果を後続の処理に受け渡す 後続の処理結果を扱う func ( ~~~~~~~~~ ) ( ~~~~~~~~~ ) { resp, err := handler(ctx, req) if err != nil { // エラーハンドリング } // 後続の処理結果をもとに実装 }
3. Google Maps APIを使った gRPCミドルウェアの実装
今回作ったもの • Google Maps APIを使ってcontextに緯度経度を追加するミドルウェア • Google Maps Geocode及びGeolocation APIの操作を可能にするパッケージを使用
◦ https://github.com/martinlindhe/google-geolocate • クライアントからのリクエストcontextに位置情報が追加されている前提 • 実際に作ったもの ◦ https://github.com/shinshin8/golang-grpc-middleware
func GeocodeUnaryServerInterceptor(apiKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { client := geo.NewGoogleGeo(apiKey) geocode := geoctx.GetGeoInfo(ctx) res, _ := client.Geocode(geocode) if err != nil { geoctx.SetGeoLocate(ctx, 0, 0) } else { geoctx.SetGeoLocate(ctx, res.Lng, res.Lat) } return handler(ctx, err) } } 実際に作ったミドルウェア
func GeocodeUnaryServerInterceptor(apiKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { client := geo.NewGoogleGeo(apiKey) ←★ 引数で受け取った Google Maps API Keyかクライアントを作成 geocode := geoctx.GetGeoInfo(ctx) res, _ := client.Geocode(geocode) if err != nil { geoctx.SetGeoLocate(ctx, 0, 0) } else { geoctx.SetGeoLocate(ctx, res.Lng, res.Lat) } return handler(ctx, err) } } 実際に作ったミドルウェア
func GeocodeUnaryServerInterceptor(apiKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { client := geo.NewGoogleGeo(apiKey) geocode := geoctx.GetGeoInfo(ctx) ←★ contextから位置情報を取得 ※geoctx.GetGeoInfoは今回作った機能 res, _ := client.Geocode(geocode) if err != nil { geoctx.SetGeoLocate(ctx, 0, 0) } else { geoctx.SetGeoLocate(ctx, res.Lng, res.Lat) } return handler(ctx, err) } } 実際に作ったミドルウェア
func GeocodeUnaryServerInterceptor(apiKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { client := geo.NewGoogleGeo(apiKey) geocode := geoctx.GetGeoInfo(ctx) res, _ := client.Geocode(geocode) ← ★ 取得した位置情報から Geocodeし、緯度経度を取得 if err != nil { geoctx.SetGeoLocate(ctx, 0, 0) } else { geoctx.SetGeoLocate(ctx, res.Lng, res.Lat) } return handler(ctx, err) } } 実際に作ったミドルウェア
func GeocodeUnaryServerInterceptor(apiKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { client := geo.NewGoogleGeo(apiKey) geocode := geoctx.GetGeoInfo(ctx) res, _ := client.Geocode(geocode) if err != nil { geoctx.SetGeoLocate(ctx, 0, 0) } else { geoctx.SetGeoLocate(ctx, res.Lng, res.Lat) ← ★ 緯度経度をcontextに付与 ※geoctx.SetGeoLocateは今回作った機能 } return handler(ctx, err) } } 実際に作ったミドルウェア
Thank you!