Skip to content

Instantly share code, notes, and snippets.

@kylelemons
Created March 3, 2013 03:24
Show Gist options
  • Save kylelemons/5074348 to your computer and use it in GitHub Desktop.
Save kylelemons/5074348 to your computer and use it in GitHub Desktop.
Type safe decoding of JSON RPC (ish) with json.RawMessage. Yes, I know this isn't precisely JSON RPC, but it's illustrative.
package main
import (
"bytes"
"encoding/json"
"log"
"os"
"strings"
)
type Request struct {
Version string `json:"jsonrpc"`
Method string `json:"method"`
ID int64 `json:"id"`
Params json.RawMessage `json:"params"`
}
type Response struct {
ID int64 `json:"id"`
Data json.RawMessage `json:"return,omitempty"`
Error string `json:"error,omitempty"`
}
type Req1 []int
type Resp1 int
func Method1(req *Req1, resp *Resp1) {
for _, v := range *req {
*(*int)(resp) += v
}
}
func main() {
msg := `
{
"id": 42,
"method": "Method1",
"params": [1, 2, 3]
}
`
var request Request
var response Response
if err := json.NewDecoder(strings.NewReader(msg)).Decode(&request); err != nil {
log.Fatalf("decode: %s", err)
}
response.ID = request.ID
switch request.Method {
case "Method1":
var in Req1
var out Resp1
if err := json.NewDecoder(bytes.NewReader(request.Params)).Decode(&in); err != nil {
log.Fatalf("decode params: %s", err)
}
Method1(&in, &out)
data, err := json.Marshal(out)
if err != nil {
log.Fatalf("encode return: %s", err)
}
response.Data = data
}
if err := json.NewEncoder(os.Stdout).Encode(&response); err != nil {
log.Fatalf("encode: %s", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment