A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://pkg.go.dev/github.com/go-kit/kit@v0.13.0/transport/http/jsonrpc below:

jsonrpc package - github.com/go-kit/kit/transport/http/jsonrpc - Go Packages

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
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4