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.3k
Google App Engine を利用した、新規 Web サービスの立ち上げ方
osamingo
23
8.5k
GAE/Go の勘どころ
osamingo
10
5.3k
Other Decks in Programming
See All in Programming
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
760
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
110
AWSに止められる覚悟してますか?
morizo_1984
2
530
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
350
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
970
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
490
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
250
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Java 27新機能 / Java 27 new features
kishida
2
220
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
550
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
240
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
50
15k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
930
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Git: the NoSQL Database
bkeepers
PRO
433
67k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Google's AI Overviews - The New Search
badams
0
1.6k
WENDY [Excerpt]
tessaabrams
14
40k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
560
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 ΛΘ͖ͤͯ·ͨ͠ɻ