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
イメージで理解するgRPC
Search
Daiki Nojiri
May 23, 2020
Programming
0
330
イメージで理解するgRPC
Daiki Nojiri
May 23, 2020
Tweet
Share
More Decks by Daiki Nojiri
See All by Daiki Nojiri
今日から書けるリーダブルコード
nojiri1098
0
480
GitのCLI操作を楽にするためにエイリアスを作った話
nojiri1098
0
290
Other Decks in Programming
See All in Programming
開発チーム・開発組織の設計改善スキルの向上
masuda220
PRO
20
11k
CJK and Unicode From a PHP Committer
youkidearitai
PRO
0
110
Kiroで始めるAI-DLC
kaonash
2
590
私の後悔をAWS DMSで解決した話
hiramax
4
210
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
10
4.1k
Ruby×iOSアプリ開発 ~共に歩んだエコシステムの物語~
temoki
0
310
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
450
Performance for Conversion! 分散トレーシングでボトルネックを 特定せよ
inetand
0
150
OSS開発者という働き方
andpad
5
1.7k
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
130
Ruby Parser progress report 2025
yui_knk
1
440
🔨 小さなビルドシステムを作る
momeemt
4
680
Featured
See All Featured
Statistics for Hackers
jakevdp
799
220k
Building an army of robots
kneath
306
46k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
The Straight Up "How To Draw Better" Workshop
denniskardys
236
140k
RailsConf 2023
tenderlove
30
1.2k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
112
20k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Transcript
ΠϝʔδͰཧղ͢Δ
ࠓͷΰʔϧ ɾH31$ͬͯͳʹʁ ɾ31$ͬͯͳʹʁ ɾͲ͏࣮ͬͯ͢Δͷʁ
ͬͯͳʹʁ
H31$ (PPHMF͕࡞ͬͨ31$ϑϨʔϜϫʔΫ
31$ͬͯͳʹʁ
31$ 3FNPUF1SPDFEVSF$BMM
31$ DMJFOU͕ࣗͷϝιουΛ࣮ߦ͢Δײ֮Ͱ TFSWFS্ͷϝιουΛ࣮ߦͰ͖Δ͘͠Έ
ͭ·ΓɺͲ͏͍͏͜ͱʁ
DMJFOUͱTFSWFSʹಉ໊ϝιου͕͋ͬͯ IUUQTJDPOTDPNJDPOTTFUTFSWFS DMJFOU TFSWFS Find() Find()
DMJFOU͕ϝιουΛ࣮ߦ͢Δͱ DMJFOU TFSWFS Find() Find() IUUQTJDPOTDPNJDPOTTFUTFSWFS
TFSWFSଆͷಉ໊ϝιου͕࣮ߦ͞Ε DMJFOU TFSWFS Find() Find() SFRVFTU IUUQTJDPOTDPNJDPOTTFUTFSWFS
ͦͷฦΓ͕DMJFOUଆͷฦΓʹͳΔ DMJFOU TFSWFS Find() Find() SFRVFTU SFTQPOTF IUUQTJDPOTDPNJDPOTTFUTFSWFS
H31$͜ͷؒΛ͏·ͬͯ͘͘ΕΔ DMJFOU TFSWFS Find() Find() SFRVFTU SFTQPOTF IUUQTJDPOTDPNJDPOTTFUTFSWFS
const res = axios.get("/api/v1/users/1") js req := FindRequest({ID: 1}) res,
err = user.Find(req) go 3&45 31$ ͜Μͳ͍ํ͕Ͱ͖·͢
Ͳ͏࣮ͬͯ͢Δͷʁ
31$Λ࣮ݱ͢Δʹ SFRVFTU DMJFOU TFSWFS SFTQPOTF IUUQTJDPOTDPNJDPOTTFUTFSWFS
ڞ௨ೝ͕ࣝඞཁ SFRVFTU DMJFOU TFSWFS SFTQPOTF ϝιουͷ໊લ ϦΫΤετͷܗࣜ Ϩεϙϯεͷܗࣜ IUUQTJDPOTDPNJDPOTTFUTFSWFS
ͦΕ͕ɺQSPUPϑΝΠϧ SFRVFTU DMJFOU TFSWFS SFTQPOTF QSPUP IUUQTJDPOTDPNJDPOTTFUTFSWFS
QSPUPϑΝΠϧͷྫ service User { rpc Find(FindRequest) returns (FindResponse) {} }
message FindRequest { int32 id = 1; } message FindResponse { string name = 1; } user_service.proto
QSPUPϑΝΠϧͷྫ user_service.proto ϦΫΤετͷܗࣜ Ϩεϙϯεͷܗࣜ service User { rpc Find(FindRequest) returns
(FindResponse) {} } message FindRequest { int32 id = 1; } message FindResponse { string name = 1; }
service User { rpc Find(FindRequest) returns (FindResponse) {} } message
FindRequest { int32 id = 1; } message FindResponse { string name = 1; } QSPUPϑΝΠϧͷྫ user_service.proto ˢϝιουͷఆٛ
QSPUP QCHP ࣍ʹɺΠϯλʔϑΣʔεΛੜ͢Δ QSPUPD QSPUPDΠϯλʔϑΣʔεΛੜ͢ΔͨΊͷίϚϯυ
QSPUP QCHP ࣍ʹɺΠϯλʔϑΣʔεΛੜ͢Δ QSPUPD ͍ΖΜͳJOUFSGBDFGVOD͕ࣗಈੜ ͞ΕΔɽਓҰ͍͡Βͳ͍
ॏཁͳ෦͚ͩϐοΫΞοϓ type UserServer interface { Find( context.Context, *FindRequest ) (*FindResponse,
error) } user_service.pb.go αʔόଆͷΠϯλʔϑΣʔε αʔόଆ͜Εʹ߹ΘͤͯϝιουΛ࣮͢Δ
ॏཁͳ෦͚ͩϐοΫΞοϓ type UserClient interface { Find( ctx context.Context, in *FindRequest,
opts ...grpc.CallOption ) (*FindResponse, error) } ΫϥΠΞϯτଆͷΠϯλʔϑΣʔε ΫϥΠΞϯτଆ͜Εʹ߹ΘͤͯϝιουΛ͏ user_service.pb.go
ॏཁͳ෦͚ͩϐοΫΞοϓ func (c *userClient) Find( ctx context.Context, in *FindRequest, opts
...grpc.CallOption ) (*FindResponse, error) { out := new(FindResponse) err := c.cc.Invoke( ctx, "/user_service.User/Find", in, out, opts... ) if err != nil { return nil, err } return out, nil } ΫϥΠΞϯτଆͷϝιου ΫϥΠΞϯτଆ͕ݺͼग़͢ϝιου࣮ࡁΈ user_service.pb.go
QSPUP QCHP ͪͳΈʹɺෳݴޠʹରԠ͍ͯ͠Δ SC KBWB
αʔόଆͷ͍ํ ؆ུ൛ import pb "path/to/pb.go" type server struct{} func (s
*server) Find( ctx context.Context, in *pb.FindRequest ) (*pb.FindResponse, error) { user := db.Find(&user) out := &pb.FindResponse{name: user.name} return out, nil } s := grpc.NewServer() pb.RegisterUserServer(s, &server{}) s.Serve(lis) server/main.go
import pb "path/to/pb.go" type server struct{} func (s *server) Find(
ctx context.Context, in *pb.FindRequest ) (*pb.FindResponse, error) { user := db.Find(&user) out := &pb.FindResponse{name: user.name} return out, nil } s := grpc.NewServer() pb.RegisterUserServer(s, &server{}) s.Serve(lis) αʔόଆͷ͍ํ ؆ུ൛ server/main.go %#͔ΒΛ औಘͯ͠ฦ͢ αʔόͷ্ཱͪ͛
ΫϥΠΞϯτଆͷ͍ํ ؆ུ൛ import pb "path/to/pb.go" c := pb.NewUserClient(conn) req :=
&pb.FindRequest{ id: 1, } resp, err := c.Find(context.Background(), req) if err != nil { log.Fatal(err) } log.Println("Name: ", resp.name) // #=> Name: alice client/main.go
ΫϥΠΞϯτଆͷ͍ํ ؆ུ൛ import pb "path/to/pb.go" c := pb.NewUserClient(conn) req :=
&pb.FindRequest{ Name: "alice", } resp, err := c.Find(context.Background(), req) if err != nil { log.Fatal(err) } log.Println("Name: ", resp.name) // #=> Name: alice client/main.go αʔόଆͷFind()ͷฦΓ
ࠓͷ·ͱΊ H31$ͬͯͳʹʁ ˠ(PPHMF͕࡞ͬͨ31$ϑϨʔϜϫʔΫ 31$ͬͯͳʹʁ ˠΫϥΠΞϯτ͔ΒαʔόͷϝιουΛݺͿ H31$Λ͏ʹʁ ˠQSPUPϑΝΠϧΛॻ͍ͯΠϯλʔϑΣʔεΛ ɹੜ͢Δ ˠੜ͞ΕͨΠϯλʔϑΣʔεΛ࣮ͬͯ͢Δ