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
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
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
1
640
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
330
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
420
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
690
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
390
AHC070解法紹介
eijirou
0
120
一人だけ、Kiroが静止する日
hideg
0
110
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
320
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.8k
Security issues being discussed on Web Platforms
petamoriken
0
950
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.2k
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.3k
Featured
See All Featured
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
58k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
700
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
65k
Designing for Timeless Needs
cassininazir
1
480
Designing Powerful Visuals for Engaging Learning
tmiket
1
550
Producing Creativity
orderedlist
PRO
348
41k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
500
A Modern Web Designer's Workflow
chriscoyier
699
190k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
460
The Cult of Friendly URLs
andyhume
79
7k
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!