/jsonrpc

Primary LanguageGo

A JSON-RPC 2.0 implementation for Go.

Supports any transport that can pass strings back and forth like WebSockets.

Example:

package main

import (
	"context"
	"errors"
	"log"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/jdxcode/jsonrpc"
)

const PORT = ":8000"

// starts a json-rpc 2.0 websocket server
func main() {
	rpc := jsonrpc.New(&RPC{})
	http.HandleFunc("/rpc", func(w http.ResponseWriter, r *http.Request) {
		upgrader := &websocket.Upgrader{}
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Println(err)
			return
		}
		ctx := r.Context()
		rpc.Handle(ctx, conn)
	})

	if err := http.ListenAndServe(PORT, nil); err != nil {
		log.Fatal(err)
	}
}

type RPC struct{}

type MyFunctionParams struct{
	ShouldError bool `json:"should_error"`
}

// the client will call this by sending a message like:
// {"jsonrpc": "2.0", id: 101, method: "ExampleFunc", params: {"should_error": false}}
// the server would respond:
// {"jsonrpc": "2.0", id: 101, result: "result can be anything json-marshalable"}
func (r *RPC) ExampleFunc(ctx context.Context, params *MyFunctionParams) (string, error) {
	if params.ShouldError {
		return "", errors.New("this error returned to client")
	}
	return "result can be anything json-marshalable", nil
}

func (r *RPC) NoParamsOrResult(ctx context.Context) error {
	return nil
}

Usage with websocat:

$ websocat --jsonrpc ws://localhost:8000/rpc
{"id":1,"method":"ExampleFunc","params":{"should_error": false}}
{"jsonrpc":"2.0","id":1,"result":"result can be anything json-marshalable"}
{"id":2,"method":"ExampleFunc","params":{"should_error": true}}
{"jsonrpc":"2.0","id":2,"error":"this error returned to client"}

# or use the --jsonrpc flag
$ websocat --jsonrpc ws://localhost:8000/rpc
ExampleFunc {}
{"jsonrpc":"2.0","id":1,"result":"result can be anything json-marshalable"}
ExampleFunc {"should_error": true}
{"jsonrpc":"2.0","id":2,"error":"this error returned to client"}