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
74k
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.4k
Google App Engine を利用した、新規 Web サービスの立ち上げ方
osamingo
23
8.5k
GAE/Go の勘どころ
osamingo
10
5.3k
Other Decks in Programming
See All in Programming
Groovy as a human and AI friendly programming language
paulk
0
180
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
4
3k
動画プレイヤーはなぜカクつくのか 〜Flutterのレンダリングとネイティブの境界を解剖する〜
naruogram
0
320
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
400
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
270
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.7k
JIS keyboard support in Omarchy
lef237
0
180
SODA - FACT BOOK(EN)
sodainc
1
200
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
290
AI Augmentation Techniques with Liberty
ivargrimstad
1
340
AmebaブログはKMPから卒業します
kmars0605
0
320
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
6
1.4k
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.8k
Code Reviewing Like a Champion
maltzj
529
40k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
920
So, you think you're a good person
axbom
PRO
2
2.2k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
Optimizing for Happiness
mojombo
378
71k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Faster Mobile Websites
deanohume
310
32k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
390
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
540
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 ΛΘ͖ͤͯ·ͨ͠ɻ