Go to file
Matt Bell 4d7aa62a10 Added test for unexpected hex string type HTTP args 2017-01-07 20:40:45 -08:00
client Handle quoted and hex string type HTTP args for both 'string' and '[]byte' type function args 2017-01-07 20:40:29 -08:00
server Handle quoted and hex string type HTTP args for both 'string' and '[]byte' type function args 2017-01-07 20:40:29 -08:00
test Added test for unexpected hex string type HTTP args 2017-01-07 20:40:45 -08:00
types use EventSwitch interface; less logging 2016-10-10 03:22:34 -04:00
LICENSE Initial commit 2016-01-12 15:26:00 -05:00
Makefile Makefile: go test --race 2016-07-22 01:15:52 -04:00
README.md link issue from readme 2016-06-23 20:40:16 -04:00
circle.yml add test example 2016-06-23 20:37:35 -04:00
rpc_test.go Handle hex strings and quoted strings in HTTP params 2017-01-07 13:59:33 -08:00
version.go support full urls (with eg tcp:// prefix) 2016-08-10 01:13:13 -04:00

README.md

go-rpc

CircleCI

HTTP RPC server supporting calls via uri params, jsonrpc, and jsonrpc over websockets

Client Requests

Suppose we want to expose the rpc function HelloWorld(name string, num int).

GET (URI)

As a GET request, it would have URI encoded parameters, and look like:

curl 'http://localhost:8008/hello_world?name="my_world"&num=5'

Note the ' around the url, which is just so bash doesn't ignore the quotes in "my_world". This should also work:

curl http://localhost:8008/hello_world?name=\"my_world\"&num=5

A GET request to / returns a list of available endpoints. For those which take arguments, the arguments will be listed in order, with _ where the actual value should be.

POST (JSONRPC)

As a POST request, we use JSONRPC. For instance, the same request would have this as the body:

{
	"jsonrpc":"2.0",
	"id":"anything",
	"method":"hello_world",
	"params":["my_world", 5]
}

Note the params does not currently support key-value pairs (https://github.com/tendermint/go-rpc/issues/1), so order matters (you can get the order from making a GET request to /)

With the above saved in file data.json, we can make the request with

curl --data @data.json http://localhost:8008

WebSocket (JSONRPC)

All requests are exposed over websocket in the same form as the POST JSONRPC. Websocket connections are available at their own endpoint, typically /websocket, though this is configurable when starting the server.

Server Definition

Define some types and routes:

// Define a type for results and register concrete versions with go-wire
type Result interface{}

type ResultStatus struct {
	Value string
}

var _ = wire.RegisterInterface(
	struct{ Result }{},
	wire.ConcreteType{&ResultStatus{}, 0x1},
)

// Define some routes
var Routes = map[string]*rpcserver.RPCFunc{
	"status": rpcserver.NewRPCFunc(StatusResult, "arg"),
}

// an rpc function
func StatusResult(v string) (Result, error) {
	return &ResultStatus{v}, nil
}

Now start the server:

mux := http.NewServeMux()
rpcserver.RegisterRPCFuncs(mux, Routes)
wm := rpcserver.NewWebsocketManager(Routes, nil)
mux.HandleFunc("/websocket", wm.WebsocketHandler)
go func() {
	_, err := rpcserver.StartHTTPServer("0.0.0.0:8008", mux)
	if err != nil {
		panic(err)
	}
}()

Note that unix sockets are supported as well (eg. /path/to/socket instead of 0.0.0.0:8008)

Now see all available endpoints by sending a GET request to 0.0.0.0:8008. Each route is available as a GET request, as a JSONRPCv2 POST request, and via JSONRPCv2 over websockets

Examples