package
0.13.0
Repository: https://github.com/go-kit/kit.git
Documentation: pkg.go.dev

# README

JSON RPC

JSON RPC is "A light weight remote procedure call protocol". It allows for the creation of simple RPC-style APIs with human-readable messages that are front-end friendly.

Using JSON RPC with Go-Kit

Using JSON RPC and go-kit together is quite simple.

A JSON RPC server acts as an HTTP Handler, receiving all requests to the JSON RPC's URL. The server looks at the method property of the Request Object, and routes it to the corresponding code.

Each JSON RPC method is implemented as an EndpointCodec, a go-kit Endpoint, sandwiched between a decoder and encoder. The decoder picks apart the JSON RPC request params, which can be passed to your endpoint. The encoder receives the output from the endpoint and encodes a JSON-RPC result.

Example — Add Service

Let's say we want a service that adds two ints together. We'll serve this at http://localhost/rpc. So a request to our sum method will be a POST to http://localhost/rpc with a request body of:

{
    "id": 123,
    "jsonrpc": "2.0",
    "method": "sum",
    "params": {
    	"A": 2,
    	"B": 2
    }
}

EndpointCodecMap

The routing table for incoming JSON RPC requests is the EndpointCodecMap. The key of the map is the JSON RPC method name. Here, we're routing the sum method to an EndpointCodec wrapped around sumEndpoint.

jsonrpc.EndpointCodecMap{
	"sum": jsonrpc.EndpointCodec{
		Endpoint: sumEndpoint,
		Decode:   decodeSumRequest,
		Encode:   encodeSumResponse,
	},
}

Decoder

type DecodeRequestFunc func(context.Context, json.RawMessage) (request interface{}, err error)

A DecodeRequestFunc is given the raw JSON from the params property of the Request object, not the whole request object. It returns an object that will be the input to the Endpoint. For our purposes, the output should be a SumRequest, like this:

type SumRequest struct {
	A, B int
}

So here's our decoder:

func decodeSumRequest(ctx context.Context, msg json.RawMessage) (interface{}, error) {
	var req SumRequest
	err := json.Unmarshal(msg, &req)
	if err != nil {
		return nil, err
	}
	return req, nil
}

So our SumRequest will now be passed to the endpoint. Once the endpoint has done its work, we hand over to the…

Encoder

The encoder takes the output of the endpoint, and builds the raw JSON message that will form the result field of a Response Object. Our result is going to be a plain int. Here's our encoder:

func encodeSumResponse(ctx context.Context, result interface{}) (json.RawMessage, error) {
	sum, ok := result.(int)
	if !ok {
		return nil, errors.New("result is not an int")
	}
	b, err := json.Marshal(sum)
	if err != nil {
		return nil, err
	}
	return b, nil
}

Server

Now that we have an EndpointCodec with decoder, endpoint, and encoder, we can wire up the server:

handler := jsonrpc.NewServer(jsonrpc.EndpointCodecMap{
	"sum": jsonrpc.EndpointCodec{
		Endpoint: sumEndpoint,
		Decode:   decodeSumRequest,
		Encode:   encodeSumResponse,
	},
})
http.Handle("/rpc", handler)
http.ListenAndServe(":80", nil)

With all of this done, our example request above should result in a response like this:

{
    "jsonrpc": "2.0",
    "result": 4
}

# Functions

BufferedStream sets whether the Response.Body is left open, allowing it to be read from later.
ClientAfter sets the ClientResponseFuncs applied to the server's HTTP response prior to it being decoded.
ClientBefore sets the RequestFuncs that are applied to the outgoing HTTP request before it's invoked.
ClientFinalizer is executed at the end of every HTTP request.
ClientRequestEncoder sets the func used to encode the request params to JSON.
ClientRequestIDGenerator is executed before each request to generate an ID for the request.
ClientResponseDecoder sets the func used to decode the response params from JSON.
DefaultErrorEncoder writes the error to the ResponseWriter, as a json-rpc error response, with an InternalError status code.
DefaultRequestEncoder marshals the given request to JSON.
DefaultResponseDecoder unmarshals the result to interface{}, or returns an error, if found.
ErrorMessage returns a message for the JSON RPC error code.
NewAutoIncrementID returns an auto-incrementing request ID generator, initialised with the given value.
NewClient constructs a usable Client for a single remote method.
NewServer constructs a new server, which implements http.Server.
ServerAfter functions are executed on the HTTP response writer after the endpoint is invoked, but before anything is written to the client.
ServerBefore functions are executed on the HTTP request object before the request is decoded.
ServerBeforeCodec functions are executed after the JSON request body has been decoded, but before the method's decoder is called.
ServerErrorEncoder is used to encode errors to the http.ResponseWriter whenever they're encountered in the processing of a request.
ServerErrorLogger is used to log non-terminal errors.
ServerFinalizer is executed at the end of every HTTP request.
SetClient sets the underlying HTTP client used for requests.

# Constants

ContentType defines the content type to be served.
InternalError defines a server error.
InvalidParamsError defines invalid method parameter(s).
InvalidRequestError defines the JSON sent is not a valid Request object.
MethodNotFoundError defines the method does not exist / is not available.
ParseError defines invalid JSON was received by the server.
Version defines the version of the JSON RPC implementation.

# Structs

Client wraps a JSON RPC method and provides a method that implements endpoint.Endpoint.
EndpointCodec defines a server Endpoint and its associated codecs.
Error defines a JSON RPC error that can be returned in a Response from the spec http://www.jsonrpc.org/specification#error_object.
Request defines a JSON RPC request from the spec http://www.jsonrpc.org/specification#request_object.
RequestID defines a request ID that can be string, number, or null.
Response defines a JSON RPC response from the spec http://www.jsonrpc.org/specification#response_object.
Server wraps an endpoint and implements http.Handler.

# Interfaces

ErrorCoder is checked by DefaultErrorEncoder.
RequestIDGenerator returns an ID for the request.

# Type aliases

ClientFinalizerFunc can be used to perform work at the end of a client HTTP request, after the response is returned.
ClientOption sets an optional parameter for clients.
DecodeRequestFunc extracts a user-domain request object from raw JSON It's designed to be used in JSON RPC servers, for server-side endpoints.
DecodeResponseFunc extracts a user-domain response object from an JSON RPC response object.
EncodeRequestFunc encodes the given request object to raw JSON.
EncodeResponseFunc encodes the passed response object to a JSON RPC result.
EndpointCodecMap maps the Request.Method to the proper EndpointCodec.
RequestFunc may take information from decoded json body and place in request context.
ServerOption sets an optional parameter for servers.