jsonrpc2: github.com/reddec/jsonrpc2 Index | Examples | Files | Directories

package jsonrpc2

import "github.com/reddec/jsonrpc2"

JSON-RPC 2.0 supporting library

Main object - Router doesn't need any kind of initialization. Just use `var router Router`.

There are two ways how to register service: dynamical and static.

Static

This is recommended way. jsonrpc2-gen tool will generate type-safe wrapper with positional and named arguments support.

Tool can be installed by `go get -v github.com/reddec/jsonrpc2/cmd/...` or by other method (see README.md)

For example:

Assume you have an interface file (`user.go`) like this:

package abc

type User interface {
	Profile(token string) (*Profile, error)
}

Just invoke `jsonrpc2-gen -i user.go -o user_gen.go -I User -p abc`

You will get `user_gen.go` file like that:

// Code generated by jsonrpc2-gen. DO NOT EDIT.
//go:generate jsonrpc2-gen -i user.go -o user_gen.go -I User -p abc
package abc

import (
	"encoding/json"
	jsonrpc2 "github.com/reddec/jsonrpc2"
)

func RegisterUser(router *jsonrpc2.Router, wrap User) []string {
	router.RegisterFunc("User.Profile", func(params json.RawMessage, positional bool) (interface{}, error) {
		var args struct {
			Arg0 string `json:"token"`
		}
		var err error
		if positional {
			err = jsonrpc2.UnmarshalArray(params, &args.Arg0)
		} else {
			err = json.Unmarshal(params, &args)
		}
		if err != nil {
			return nil, err
		}
		return wrap.Profile(args.Arg0)
	})

	return []string{"User.Profile"}
}

Dynamic

By using RegisterPositionalOnly or RegisterNamedOnly. This two functions are heavily relying on reflection so don't use in a high-load environment.

HTTP expose

Helper `Handler` can expose JSON-RPC over HTTP with supported methods POST, PUT, PATCH. For other methods server will return MethodNotAllowed (405)

Index

Examples

Package Files

doc.go router.go support.go types.go

Constants

const (
    Version        = "2.0"
    AppError       = -30000
    ParseError     = -32700
    InvalidRequest = -32600
    MethodNotFound = -32601
    InvalidParams  = -32602
    InternalError  = -32603
)

func Function Uses

func Function(handler interface{}) (*callableWrapper, error)

Wrap function as JSON-RPC method for usage in router

This kind of wrapper support only positional arguments

func Handler Uses

func Handler(router *Router) http.HandlerFunc

Expose JSON-RPC router as HTTP handler. Supported methods: POST, PUT, PATCH

Code:

var router Router
router.RegisterPositionalOnly("sum", func(a, b int) (int, error) {
    return a + b, nil
})
http.ListenAndServe(":8080", Handler(&router))

func RPCLike Uses

func RPCLike(handler interface{}) (*rpcLikeCallable, error)

Expose function handler where first argument is pointer to structure and returns are payload with error.

This kind of wrapper support only named arguments

func ToArray Uses

func ToArray(params json.RawMessage, expected int) ([]json.RawMessage, error)

func UnmarshalArray Uses

func UnmarshalArray(params json.RawMessage, args ...interface{}) error

type Error Uses

type Error struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data,omitempty"`
}

JSON-RPC 2.0 standard error object

func (*Error) Error Uses

func (e *Error) Error() string

type GlobalInterceptorContext Uses

type GlobalInterceptorContext struct {
    Requests []*Request
    IsBatch  bool
    // contains filtered or unexported fields
}

func (*GlobalInterceptorContext) Next Uses

func (gic *GlobalInterceptorContext) Next() (responses []*Response, isBatch bool)

type GlobalInterceptorFunc Uses

type GlobalInterceptorFunc func(gic *GlobalInterceptorContext) (responses []*Response, isBatch bool)

func MaxBatch Uses

func MaxBatch(num int) GlobalInterceptorFunc

Interceptor that limiting maximum number of requests in a batch. If batch size is bigger - InternalError will be returned with description. Only one error response without ID will be generated regardless of batch size

type Method Uses

type Method interface {
    JsonCall(params json.RawMessage, positional bool) (interface{}, error)
}

Method handler (for low-level implementation). Should support params as object or as array (positional=true).

Returned data should be JSON serializable and not nil for success

type MethodFunc Uses

type MethodFunc func(params json.RawMessage, positional bool) (interface{}, error)

func (MethodFunc) JsonCall Uses

func (m MethodFunc) JsonCall(params json.RawMessage, positional bool) (interface{}, error)

type MethodInterceptorContext Uses

type MethodInterceptorContext struct {
    Request      *Request
    IsPositional bool
    // contains filtered or unexported fields
}

Context handling request per method

func (*MethodInterceptorContext) Next Uses

func (ic *MethodInterceptorContext) Next() (interface{}, error)

Call next interceptor or final method

type MethodInterceptorFunc Uses

type MethodInterceptorFunc func(ic *MethodInterceptorContext) (interface{}, error)

Interceptor for each method that will be called

type Request Uses

type Request struct {
    // always 2.0 (will refuse if not)
    Version string `json:"jsonrpc"`
    // case-sensitive method name
    Method string `json:"method"`
    // any kind of valid JSON as ID (more relaxed comparing to for spec)
    ID  json.RawMessage `json:"id"`
    // array (for positional) or object (for named) of arguments
    Params json.RawMessage `json:"params"`
}

Standard JSON-RPC 2.0 request messages

func (*Request) IsNotification Uses

func (rq *Request) IsNotification() bool

Check request is notification (null ID)

func (*Request) IsValid Uses

func (rq *Request) IsValid() bool

Base checks against specification

type Response Uses

type Response struct {
    // always 2.0
    Version string `json:"jsonrpc"`
    // any kind of valid JSON as ID (more relaxed comparing to for spec) copied from request
    ID  json.RawMessage `json:"id"`
    // result if exists
    Result interface{} `json:"result,omitempty"`
    // error if exists
    Error *Error `json:"error,omitempty"`
}

JSON-RPC 2.0 standard response object

type Router Uses

type Router struct {
    // contains filtered or unexported fields
}

Router for JSON-RPC requests.

Supports batching.

func (*Router) Intercept Uses

func (caller *Router) Intercept(handler GlobalInterceptorFunc) *Router

Add interceptor for handling batch before lookup for methods and execution

func (*Router) InterceptMethods Uses

func (caller *Router) InterceptMethods(handler MethodInterceptorFunc) *Router

Add interceptor for handling all methods invoke. Called in a same thread as method

func (*Router) Invoke Uses

func (caller *Router) Invoke(stream io.Reader) (responses []*Response, isBatch bool)

Invoke exposed method using request from stream (as a batch or single)

func (*Router) Register Uses

func (caller *Router) Register(method string, handler Method) *Router

Register method to router to expose over JSON-RPC interface

func (*Router) RegisterFunc Uses

func (caller *Router) RegisterFunc(method string, handlerFunc MethodFunc) *Router

Register function as method to expose over JSON-RPC

func (*Router) RegisterNamedOnly Uses

func (caller *Router) RegisterNamedOnly(method string, handler interface{}) error

Register function as exposed method. Function handler must have first argument is pointer to structure and must return payload and error.

This kind of wrapper supports only named arguments.

Code:

type Args struct {
    A   int `json:"a"`
    B   int `json:"b"`
}
router := &Router{}
err := router.RegisterNamedOnly("sum", func(params *Args) (int, error) {
    return params.A + params.B, nil
})
if err != nil {
    panic(err)
}

func (*Router) RegisterPositionalOnly Uses

func (caller *Router) RegisterPositionalOnly(method string, handler interface{}) error

Register function as exposed method. Handler must return two values, last of them - error.

For such methods only positional arguments supported.

Code:

router := &Router{}
err := router.RegisterPositionalOnly("sum", func(a, b int) (int, error) {
    return a + b, nil
})
if err != nil {
    panic(err)
}

Directories

PathSynopsis
example

Package jsonrpc2 imports 10 packages (graph). Updated 2020-03-26. Refresh now. Tools for package owners.