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
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
220
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
1
270
Groovy as a human and AI friendly programming language
paulk
0
180
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
140
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
200
AIが実装を担う時代の「技術設計」と「チームマネジメント」
kamina_zzz
1
130
動画プレイヤーはなぜカクつくのか 〜Flutterのレンダリングとネイティブの境界を解剖する〜
naruogram
0
320
Engineering Biometric UX Across Android Versions | DroidKnights 2026
ryunen344
1
170
AI時代のFlutter品質設計 — アプリ品質を守るQuality Layers
omatty198
0
350
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
120
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
170
AmebaブログはKMPから卒業します
kmars0605
0
320
Featured
See All Featured
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
3k
Ethics towards AI in product and experience design
skipperchong
2
460
ラッコキーワード サービス紹介資料
rakko
5
5.7M
Visualization
eitanlees
153
17k
Paper Plane (Part 1)
katiecoart
PRO
2
12k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
460
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
400
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
It's Worth the Effort
3n
188
29k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
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 ΛΘ͖ͤͯ·ͨ͠ɻ