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
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
550
Swift愛好会100回記念 第1回を振り返る
jollyjoester
0
120
Heart of Swift Concurrency
koher
0
240
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
150
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2k
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
650
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
180
信頼性の目標を誰も求めてない
shubox
0
500
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
高専キャリア LT 発表内容
crysta1221
6
5.7k
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
140
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
A Soul's Torment
seathinner
7
3.6k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Done Done
chrislema
186
16k
Abbi's Birthday
coloredviolet
3
9.9k
The Curse of the Amulet
leimatthew05
2
14k
How STYLIGHT went responsive
nonsquared
100
6.3k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
A Tale of Four Properties
chriscoyier
163
24k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
570
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 ΛΘ͖ͤͯ·ͨ͠ɻ