Go で始める JSON-RPC 入門
この記事は、 Go Advent Calendar 2016 の 15 日目の記事です。
みなさんは、JSON-RPC を使ったことがありますか?
この記事では、 Go で JSON-RPC を使用する方法をレクチャーしたいと思います。(※ この記事は、 golang.tokyo #2 での LT 内容をベースに加筆修正を加えたものになります。)
JSON-RPC とは
概要
JSON-RPC は、 JSON を媒体とした Remote Procedure Call です。
そのため、 Content-Type: application/json
で Request と Response をやり取りします。また、 RPC なので Endpoint も任意で決めた Path のみとなります。
JSON-RPC の利点のひとつに、新しく覚える要素がほとんど無いという点があります。最新の仕様である、 JSON-RPC 2.0 も、コンパクトな内容でシンプルです。
簡単な例
Echo
という method を定義し、Request で name
を受け取ったら、 Response の message
という Property に Hello, {{name}}
という文字列を生成して返却するとします。
そうすると、Request は、
{
"jsonrpc": "2.0",
"method": "Echo",
"params": {
"name": "John Doe"
},
"id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b"
}
となり、 Response は、
{
"jsonrpc": "2.0",
"result": {
"message": "Hello, John Doe"
},
"id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b"
}
となります。
標準 Package での JSON-RPC
Go には、 net/rpc/jsonrpc というPackage があり、標準で JSON-RPC をサポートしています。
実装例
上記のように実装することが、出来ます。
また、上記の実装では省いていますが、 Debug Handler も付属しており、登録済みの Method 一覧と Call 数を確認することが出来ます。
標準 Package での所感
- 実装を通して、 RPC をレクチャーしてくれる Go らしさを感じる。
- JSON-RPC 2.0 の仕様は満たしていない。
- HTTP で受け取るには、
net.Conn
を取り出さないといけない。 - Package 内を覗くと
reflect
を多用している印象がある。
Third Party Package での JSON-RPC
Gorilla Toolkit が、JSON-RPC 2.0 の仕様を実装してくれています。
実装例
上記のように実装することが、出来ます。
定義してある、 Interface が変更されていて、第一引数で *http.Request
を受け取ることが出来るようになっています。また、 net.Conn
を取り出すことも無く、 Codec を登録し Handler を Endpoint に設定するだけになっています。
Gorilla Toolkit での所感
- 標準 Package を踏襲しつつ、扱いやすくなっている。
- Go 1.6 以下だと、
context.Context
を持ち運べない。 - Custom Error を返却したい場合 data を書き込めないなど、すこし手の届かないところがある。
オススメの Package
結構、いろいろな Package を見て回ったのですが…、ありませんでした。
ないので、 github.com/osamingo/jsonrpc を作りました。
実装例
上記のように実装することが、出来ます。
各 Method に対応する jsonrpc.Func
を満たす関数を定義して行きます。 jsonrpc.RegisterMethod
に Method 名と関数を登録し、 Endpoint を設定します。
Gorilla Toolkit との差異
reflect
を使わず、 Method Repository という形で、 map を利用して Method 名と関数ポインタを紐付けています。- Go の Version に関わらず、
context.Context
を持ち運ぶようにしています。 Google App Engine の Standerd Environment に対応しています。 - Endpoint が任意で決めた Path のみとなり Swagger や、 API Blueprint 等のツールに対応出来ません。
なので、 Debug Handler を用意し、登録してある Method 一覧と各 Method に紐付く Params, Result の JSON Schema を自動生成するようにしました。具体的には、下記のような Response を返却します。
まとめ
全体を通して、まとめるとこのような感じになります。
- JSON-RPC は既存知識の組み合わせなので、シンプル且つ簡単である。
- Go は、標準 Package で、 JSON-RPC をサポートしている。
- Gorilla Toolkit は、標準 Package を踏襲しつつ、JSON-RPC 2.0 の仕様を実装してくれている。
- osamingo/jsonrpc は、JSON-RPC 2.0 の仕様を満たし、よりシンプルに、より Debug しやすくなっている。また、
context.Context
をサポートしているので、 Google App Engine でも使える。
Go で始める JSON-RPC 入門は、いかがだったでしょうか。
仕様自体もとてもシンプルで、 RPC を学ぶ上では分かりやすい例だったと思います。この記事が、お役に立てれれば幸いです。
明日の Go Advent Calendar 2016 は、 @yuin さんです。