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
Go で始める JSON-RPC 入門
Search
Osamu TONOMORI
December 12, 2016
Programming
73k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Go で始める JSON-RPC 入門
Osamu TONOMORI
December 12, 2016
More Decks by Osamu TONOMORI
See All by Osamu TONOMORI
About Merpay Architect Team 2021
osamingo
0
1.8k
Gopher's Travel Journal 2018
osamingo
1
1.9k
Go のライブラリやっていき 💪 #go #golang / Let's creating a original library by Go
osamingo
3
2.3k
Google App Engine を利用した、新規 Web サービスの立ち上げ方
osamingo
23
8.5k
GAE/Go の勘どころ
osamingo
10
5.3k
Other Decks in Programming
See All in Programming
Verilogで学ぶCPU自作入門.pdf
uyuki234
2
870
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
220
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
1
9.2k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
260
iOSDC2026登壇資料.pdf
riofujimon
0
180
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
560
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
160
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
510
一人だけ、Kiroが静止する日
hideg
0
130
Agents on Rails - Rails at Scale 2026
irinanazarova
0
150
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
500
setup-vp GitLab対応の裏側
naokihaba
0
120
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.2k
Crafting Experiences
bethany
1
350
The Cost Of JavaScript in 2023
addyosmani
55
10k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
470
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Amusing Abliteration
ianozsvald
1
310
Automating Front-end Workflow
addyosmani
1369
210k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Tell your own story through comics
letsgokoyo
1
1.1k
How to Ace a Technical Interview
jacobian
281
24k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Transcript
Go Ͱ࢝ΊΔ JSON-RPC ೖ @osamingo golang.tokyo #2 (2016/12/12)
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
ࣗݾհ
ࣗݾհ • ओ ཧ - Osamu TONOMORI • @osamingo •
גࣜձࣾικ • 2016/08 ~ • Software engineer • Go ྺ • 2014/10 ~ • 3 services • <3 Live, Juggling, Voice Percussion 5
None
None
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
JSON-RPC #ͱ
JSON-RPC #ͱ • JSON Λར༻ͨ͠ɺRemote Procedure Call Ͱ͢ɻ • Content-Type:
“application/json" • Path: “/jrpc” • Specification ͕ɺ΄΅ϖϥΠν͔͠ͳ͍ɻ • ৽֮͑͘͠Δ͜ͱɺ΄΅ͳ͍ɻ • http://www.jsonrpc.org/specification 10
None
JSON-RPC Example - Request 12 1 { 2 "jsonrpc": "2.0",
3 "method": "Echo", 4 "params": { 5 "name": "John Doe" 6 }, 7 "id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b" 8 }
JSON-RPC Example - Response 13 1 { 2 "jsonrpc": "2.0",
3 "result": { 4 "message": "Hello, John Doe" 5 }, 6 "id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b" 7 }
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
ඪ४ Package Ͱͷ JSON-RPC
ඪ४ Package Ͱͷ JSON-RPC • Go ɺඪ४Ͱ JSON-RPC Λαϙʔτ͍ͯ͠·͢ɻ •
import “net/rpc/jsonrpc” • Go BlogͰհ͋ΔͷͰׂΓͱ͍ͬͯΔਓଟ͍͔ • https://blog.golang.org/json-rpc-tale-of-interfaces 16
JSON-RPC by net/rpc/jsonrpc 1 package main 2 3 import (
4 "io" 5 "log" 6 "net" 7 "net/http" 8 "net/rpc" 9 "net/rpc/jsonrpc" 10 ) 11 12 type ( 13 Arithmetic struct{} 14 MultiplyArgs struct { 15 A, B int 16 } 17 MultiplyResult struct { 18 Result int 19 } 20 ) 21 22 func (a *Arithmetic) Multiply(args *MultiplyArgs, reply *MultiplyResult) error { 23 reply.Result = args.A * args.B 24 return nil 25 } 26 27 func init() { 28 s := rpc.NewServer() 29 arithmetic := &Arithmetic{} 30 s.Register(arithmetic) 31 http.HandleFunc("/jrpc", func(w http.ResponseWriter, r *http.Request) { 32 conn, _, err := w.(http.Hijacker).Hijack() 33 if err != nil { 34 log.Fatalln(err) 35 } 36 s.ServeCodec(jsonrpc.NewServerCodec(conn)) 37 }) 38 39 go http.ListenAndServe(":8080", nil) 40 } 41 42 func main() { 43 conn, err := net.Dial("tcp", "localhost:8080") 44 if err != nil { 45 log.Fatalln(err) 46 } 47 io.WriteString(conn, "CONNECT "+"/jrpc"+" HTTP/1.0\n\n") 48 if err != nil { 49 log.Fatalln(err) 50 } 51 cli := jsonrpc.NewClient(conn) 52 var ret MultiplyResult 53 err = cli.Call("Arithmetic.Multiply", &MultiplyArgs{A: 5, B: 5}, &ret) 54 if err != nil { 55 log.Fatalln(err) 56 } 57 defer cli.Close() 58 log.Println(ret.Result) 59 } https://git.io/v1gpF 17
JSON-RPC by net/rpc/jsonrpc • ·ͣɺड͚͚Δ Method Λ༻ҙ͢Δɻ 12 type (
13 Arithmetic struct{} 14 MultiplyArgs struct { 15 A, B int 16 } 17 MultiplyResult struct { 18 Result int 19 } 20 ) 21 22 func (a *Arithmetic) Multiply(args *MultiplyArgs, reply *MultiplyResult) error { 23 reply.Result = args.A * args.B 24 return nil 25 } 18
JSON-RPC by net/rpc/jsonrpc • RPC Server ʹొ͢Δɻ • HTTP Ͱͷ
Handling Λઃఆ͢Δɻ 27 func init() { 28 s := rpc.NewServer() 29 arithmetic := &Arithmetic{} 30 s.Register(arithmetic) 31 http.HandleFunc("/jrpc", func(w http.ResponseWriter, r *http.Request) { 32 conn, _, err := w.(http.Hijacker).Hijack() 33 if err != nil { 34 log.Fatalln(err) 35 } 36 s.ServeCodec(jsonrpc.NewServerCodec(conn)) 37 }) 38 39 go http.ListenAndServe(":8080", nil) 40 } 19
JSON-RPC by net/rpc/jsonrpc • ϝιου໊Λࢦఆͯ͠ CONNECT͢Δɻ 42 func main() {
43 conn, err := net.Dial("tcp", "localhost:8080") 44 if err != nil { 45 log.Fatalln(err) 46 } 47 io.WriteString(conn, "CONNECT "+"/jrpc"+" HTTP/1.0\n\n") 48 if err != nil { 49 log.Fatalln(err) 50 } 51 cli := jsonrpc.NewClient(conn) 52 var ret MultiplyResult 53 err = cli.Call("Arithmetic.Multiply", &MultiplyArgs{A: 5, B: 5}, &ret) 54 if err != nil { 55 log.Fatalln(err) 56 } 57 defer cli.Close() 58 log.Println(ret.Result) 59 } 20
JSON-RPC by net/rpc/jsonrpc • Debug ػೳ͍ͭͯΔ 21
ݸਓతͳײ • ࣮Λ௨ͯ͠ɺ RPC ΛϨΫνϟʔͯ͘͠Ε͍ͯΔɻ • JSON-RPC 2.0 ͷ Spec
Λຬ͍ͨͯ͠ͳ͍ɻ • HTTP Ͱड͚औΔ࣌ʹͪΐͬͱख͕͔͔ؒΔɻ • Reflect ͕ɺଟ͍ؾ͕͢Δɻ 22
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
Third Party Package Ͱͷ JSON-RPC
Gorilla Toolkit ͷ JSON-RPC • Gorilla Toolkit ͕ɺ Spec Λىͯ͘͜͠Ε͍ͯΔɻ
• import “github.com/gorilla/rpc/v2/json2" • Interface ͕ɺѻ͍͘͢ͳ͍ͬͯΔɻ 25
JSON-RPC by Gorilla Toolkit https://git.io/v1VeT 26 1 package main 2
3 import ( 4 "bytes" 5 "log" 6 "net/http" 7 8 "github.com/gorilla/rpc/v2" 9 "github.com/gorilla/rpc/v2/json2" 10 ) 11 12 type ( 13 Arithmetic struct{} 14 MultiplyArgs struct { 15 A, B int 16 } 17 MultiplyResult struct { 18 Result int 19 } 20 ) 21 22 func (a *Arithmetic) Multiply(r *http.Request, args *MultiplyArgs, reply *MultiplyResult) error { 23 reply.Result = args.A * args.B 24 return nil 25 } 26 27 func init() { 28 s := rpc.NewServer() 29 s.RegisterCodec(json2.NewCodec(), "application/json") 30 arithmetic := &Arithmetic{} 31 s.RegisterService(arithmetic, "") 32 http.Handle("/jrpc", s) 33 go http.ListenAndServe(":8080", nil) 34 } 35 36 func main() { 37 resp, err := http.Post("http://localhost:8080/jrpc", "application/json", 38 bytes.NewBufferString(`{ 39 "jsonrpc": "2.0", 40 "method": "Arithmetic.Multiply", 41 "params": { 42 "A": 10, 43 "B": 10 44 }, 45 "id": 123 46 }`)) 47 if err != nil { 48 log.Fatalln(err) 49 } 50 defer resp.Body.Close() 51 var ret MultiplyResult 52 err = json2.DecodeClientResponse(resp.Body, &ret) 53 if err != nil { 54 log.Println("aaa") 55 log.Fatalln(err) 56 } 57 log.Println(ret.Result) 58 }
JSON-RPC by Gorilla Toolkit • http.Request ͕ड͚औΕΔ༷ʹͳ͍ͬͯΔɻ 27 22 func
(a *Arithmetic) Multiply(r *http.Request, args *MultiplyArgs, reply *MultiplyResult) error { 23 reply.Result = args.A * args.B 24 return nil 25 }
JSON-RPC by Gorilla Toolkit • net.Conn ΛऔΓճ͞ͳͯ͘େৎʹͳ͍ͬͯΔɻ • Content-Type ͱ
Codec ΛηοτͰఆٛͰ͖Δɻ 28 27 func init() { 28 s := rpc.NewServer() 29 s.RegisterCodec(json2.NewCodec(), "application/json") 30 arithmetic := &Arithmetic{} 31 s.RegisterService(arithmetic, "") 32 http.Handle("/jrpc", s) 33 go http.ListenAndServe(":8080", nil) 34 }
JSON-RPC by Gorilla Toolkit • ݟͨ͜ͱ͋Δ HTTP Request ͷඈ͠ํͰΠέΔɻ 29
36 func main() { 37 resp, err := http.Post("http://localhost:8080/jrpc", "application/json", 38 bytes.NewBufferString(`{ 39 "jsonrpc": "2.0", 40 "method": "Arithmetic.Multiply", 41 "params": { 42 "A": 10, 43 "B": 10 44 }, 45 "id": 123 46 }`)) 47 if err != nil { 48 log.Fatalln(err) 49 } 50 defer resp.Body.Close() 51 var ret MultiplyResult 52 err = json2.DecodeClientResponse(resp.Body, &ret) 53 if err != nil { 54 log.Println("aaa") 55 log.Fatalln(err) 56 } 57 log.Println(ret.Result) 58 }
ݸਓతͳײ • ඪ४ Package Λ౿ऻ͠ɺѻ͍͘͢ͳ͍ͬͯΔɻ • Go 1.6 ҎԼͩͱɺ context
Λ࣋ͪӡͳ͍ɻ • ͢͜͠खͷಧ͔ͳ͍෦͕͋Δɻ ྫʣCustom Error ࣌ͷ Data ͷॻ͖ࠐΊͳ͍ 30
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
Φεεϝͷ Package
ͳ͍
ͷͰɺ࡞Γ·ͨ͠ɻ
github.com/osamingo/jsonrpc
JSON-RPC by osamingo/jsonrpc • ؆ૉͳ࣮ • context Λ࣋ͪӡΔ • ΑΓৄࡉͳ
Debug ػೳ 36
JSON-RPC by osamingo/jsonrpc 37 1 package main 2 3 import
( 4 "bytes" 5 "context" 6 "encoding/json" 7 "log" 8 "net/http" 9 10 "github.com/osamingo/jsonrpc" 11 ) 12 13 type ( 14 MultiplyParams struct { 15 A, B int 16 } 17 MultiplyResult struct { 18 Result int 19 } 20 ) 21 22 var _ jsonrpc.Func = Multiply 23 24 func Multiply(c context.Context, params *json.RawMessage) (interface{}, *jsonrpc.Error) { 25 var p MultiplyParams 26 if err := jsonrpc.Unmarshal(params, &p); err != nil { 27 return nil, err 28 } 29 return MultiplyResult{ 30 Result: p.A * p.B, 31 }, nil 32 } 33 34 func init() { 35 jsonrpc.RegisterMethod("Arithmetic.Multiply", Multiply, MultiplyParams{}, MultiplyResult{}) 36 http.HandleFunc("/jrpc", jsonrpc.Handler) 37 http.HandleFunc("/jrpc/debug", jsonrpc.DebugHandler) 38 go http.ListenAndServe(":8080", nil) 39 } 40 41 func main() { 42 resp, err := http.Post("http://localhost:8080/jrpc", "application/json", 43 bytes.NewBufferString(`{ 44 "jsonrpc": "2.0", 45 "method": "Arithmetic.Multiply", 46 "params": { 47 "A": 15, 48 "B": 15 49 }, 50 "id": 456 51 }`)) 52 if err != nil { 53 log.Fatalln(err) 54 } 55 defer resp.Body.Close() 56 var body jsonrpc.Response 57 if err := json.NewDecoder(resp.Body).Decode(&body); err != nil { 58 log.Fatalln(err) 59 } 60 log.Println(body.Result.(map[string]interface{})["Result"]) 61 } https://git.io/v1Vew
JSON-RPC by osamingo/jsonrpc • jsonrpc.Func Λຬͨؔ͢Λఆٛ͢Δɻ 38 13 type (
14 MultiplyParams struct { 15 A, B int 16 } 17 MultiplyResult struct { 18 Result int 19 } 20 ) 21 22 var _ jsonrpc.Func = Multiply 23 24 func Multiply(c context.Context, params *json.RawMessage) (interface{}, *jsonrpc.Error) { 25 var p MultiplyParams 26 if err := jsonrpc.Unmarshal(params, &p); err != nil { 27 return nil, err 28 } 29 return MultiplyResult{ 30 Result: p.A * p.B, 31 }, nil 32 }
JSON-RPC by osamingo/jsonrpc • Method Λొ͠ɺEndpoint Λఆٛ͢Δɻ 39 34 func
init() { 35 jsonrpc.RegisterMethod("Arithmetic.Multiply", Multiply, MultiplyParams{}, MultiplyResult{}) 36 http.HandleFunc("/jrpc", jsonrpc.Handler) 37 http.HandleFunc("/jrpc/debug", jsonrpc.DebugHandler) 38 go http.ListenAndServe(":8080", nil) 39 }
JSON-RPC by osamingo/jsonrpc • Request ɺGorilla ͱ΄΅มΘΒͳ͍ײ͡ɻ 40 41 func
main() { 42 resp, err := http.Post("http://localhost:8080/jrpc", "application/json", 43 bytes.NewBufferString(`{ 44 "jsonrpc": "2.0", 45 "method": "Arithmetic.Multiply", 46 "params": { 47 "A": 15, 48 "B": 15 49 }, 50 "id": 456 51 }`)) 52 if err != nil { 53 log.Fatalln(err) 54 } 55 defer resp.Body.Close() 56 var body jsonrpc.Response 57 if err := json.NewDecoder(resp.Body).Decode(&body); err != nil { 58 log.Fatalln(err) 59 } 60 log.Println(body.Result.(map[string]interface{})["Result"]) 61 }
JSON-RPC by osamingo/jsonrpc • MethodRepository ͱ͍͏ܗͰɺmap Λͬͯ ϝιου໊ͱؔͷϙΠϯλΛඥ͚͍ͯ·͢ɻ • Go
ͷόʔδϣϯʹ͔͔ΘΒͣɺcontext ͷ࣋ͪӡͼʹ ରԠ͍ͯ͠·͢ɻʢ<3 GAE/SEʣ 41
ͱ͍͑ • JSON-RPC ͩͱɺSwagger ͱ͔ɺAPI Blueprint ͱ͔ ͑ͳͯ͘ɺ݁ہίʔυಡΜͰԼ͍͞ͱ͔͠ݴ͑ͳ͍݅ 42
ͱ͍͑ • JSON-RPC ͩͱɺSwagger ͱ͔ɺAPI Blueprint ͱ͔ ͑ͳͯ͘ɺ݁ہίʔυಡΜͰԼ͍͞ͱ͔͠ݴ͑ͳ͍݅ => Debug
ػೳ͑ JSON Schema ͕ฦͬͯ͘Δɻ 43
JSON-RPC by osamingo/jsonrpc 44 1 [ 2 { 3 "name":
"Arithmetic.Multiply", 4 "function": "main.Multiply", 5 "params": { 6 "$ref": "#/definitions/MultiplyParams", 7 "definitions": { 8 "MultiplyParams": { 9 "type": "object", 10 "properties": { 11 "A": { 12 "type": "integer" 13 }, 14 "B": { 15 "type": "integer" 16 } 17 }, 18 "additionalProperties": false, 19 "required": [ 20 "A", 21 "B" 22 ] 23 } 24 } 25 }, 26 "result": { 27 "$ref": "#/definitions/MultiplyResult", 28 "definitions": { 29 "MultiplyResult": { 30 "type": "object", 31 "properties": { 32 "Result": { 33 "type": "integer" 34 } 35 }, 36 "additionalProperties": false, 37 "required": [ 38 "Result" 39 ] 40 } 41 } 42 } 43 } 44 ] ొͯ͋͠Δϝιου໊ Params ͷ JSON Schema Resultͷ JSON Schema
Agenda 1. ࣗݾհ 2. JSON-RPC #ͱ 3. ඪ४ Package Ͱ
JSON-RPC 4. Third Party Package Ͱͷ JSON-RPC 5. Φεεϝͷ Package 6. ·ͱΊ
·ͱΊ
·ͱΊ • JSON-RPC ɺεΰ͘؆୯Ͱ͋Δɻ • Go ݴޠɺඪ४ Package Ͱαϙʔτ͍ͯ͠Δɻ •
Gorilla Toolkit ɺJSON-RPC 2.0 Λຬ͍ͨͯ͠Δɻ • osamingo/jsonrpc Λͬͯ͘ΕΔͱخ͍͠ɻ (awesome-go ʹొࡁΈͩΑɻ)
Next xRPC is … ͱ͍͑ɺ࣍དྷΔʢདྷ͍ͯΔʣRPC ɺgRPC Ͱ͢ɻ
Thank you for your attention. ελΠϧɺ@shoya140 ۘͷ Zebra ΛΘ͖ͤͯ·ͨ͠ɻ