jrpc

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2022 License: MIT Imports: 15 Imported by: 5

README

jrpc - rpc with json Build Go Report Card Coverage Status godoc

jrpc library provides client and server for RPC-like communication over HTTP with json encoded messages. The protocol is a somewhat simplified version of json-rpc with a single POST call sending Request json (method name and the list of parameters) moreover, receiving json Response with result data and an error string.

Usage

Plugin (server)
// Plugin wraps jrpc.Server and adds synced map to store data
type Plugin struct {
	*jrpc.Server
}

// create plugin (jrpc server) with NewServer where required param is a base url for rpc calls
plugin := NewServer("/command")

// then add you function to map 
plugin.Add("mycommand", func(id uint64, params json.RawMessage) Response {
    return jrpc.EncodeResponse(id, "hello, it works", nil)
})

// and run server with port number value
plugin.Run(9090)

The constructor NewServer accept two parameters:

  • API - a base url for rpc calls
  • Options - optional parameters such is timeouts, logger, limits, middlewares and etc.
    • Auth - set credentials basic auth to server, accepts username and password
    • WithTimeout - sets global timeouts for server requests, such as read, write and idle. Call accept Timeouts struct.
    • WithLimits - define limit for server call, accepts limit value in float64 type
    • WithThrottler - sets throttler middleware with specify limit value
    • WithtSignature - sets server signature, accept appName, author and version. Disable by default.
    • WithLogger - define custom logger (e.g. lgr)
    • WithMiddlewares - sets custom middlewares list to server, accepts list of handler with idiomatic type func(http.Handler) http.Handler

Example with options:

plugin := NewServer("/command",
	    Auth("user", "password"),
		WithTimeout(Timeouts{ReadHeaderTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, IdleTimeout: 10 * time.Second}),
		WithThrottler(120),
		WithLimits(100),
        WithtSignature("the best plugin ever", "author", "1.0.0"),
		WithMiddlewares(middleware.Heartbeat('/ping'), middleware.Profiler, middleware.StripSlashes),
)
Application (client)
// Client makes jrpc.Client and invoke remote call
rpcClient := jrpc.Client{
    API:        "http://127.0.0.1:8080/command",
    Client:     http.Client{},
    AuthUser:   "user",
    AuthPasswd: "password",
}

resp, err := rpcClient.Call("mycommand")
var message string
if err = json.Unmarshal(*resp.Result, &message); err != nil {
    panic(err)
}

for functional examples for both plugin and application see _example

Technical details

  • jrpc.Server runs on user-defined port as a regular http server
  • Server accepts a single POST request on user-defined url with Request sent as json payload
request details and an example:
 ```go
 type Request struct {
 	Method string      `json:"method"`
 	Params interface{} `json:"params,omitempty"`
 	ID     uint64      `json:"id"`
 }
 ```
 example: 
 
 ```json
   {
    "method":"test",
    "params":[123,"abc"],
    "id":1
    }
 ```
  • Params can be a struct, primitive type or slice of values, even with different types.
  • Server defines ServerFn handler function to react on a POST request. The handler provided by the user.
  • Communication between the server and the caller can be protected with basic auth.
  • Client provides a single method Call and return Response
response details:
 // Response encloses result and error received from remote server
 type Response struct {
 	Result *json.RawMessage `json:"result,omitempty"`
 	Error  string           `json:"error,omitempty"`
 	ID     uint64           `json:"id"`
 }
  • User should encode and decode json payloads on the application level, see provided examples
  • jrpc.Server doesn't support https internally (yet). If used on exposed or non-private networks, should be proxied with something providing https termination (nginx and others).

Status

The code was extracted from remark42 and still under development. Until v1.x released the API & protocol may change.

Documentation

Overview

Package jrpc implements client and server for RPC-like communication over HTTP with json encoded messages. The protocol is somewhat simplified version of json-rpc with a single POST call sending Request json (method name and the list of parameters) and receiving back json Response with "result" json and error string

Index

Constants

This section is empty.

Variables

View Source
var NoOpLogger = LoggerFunc(func(format string, args ...interface{}) {})

NoOpLogger logger does nothing

Functions

This section is empty.

Types

type Client

type Client struct {
	API        string      // URL to jrpc server with entrypoint, i.e. http://127.0.0.1:8080/command
	Client     http.Client // http client injected by user
	AuthUser   string      // basic auth user name, should match Server.AuthUser, optional
	AuthPasswd string      // basic auth password, should match Server.AuthPasswd, optional
	// contains filtered or unexported fields
}

Client implements remote engine and delegates all calls to remote http server if AuthUser and AuthPasswd defined will be used for basic auth in each call to server

func (*Client) Call

func (r *Client) Call(method string, args ...interface{}) (*Response, error)

Call remote server with given method and arguments. Empty args will be ignored, single arg will be marshaled as-us and multiple args marshaled as []interface{}. Returns Response and error. Note: Response has it's own Error field, but that onw controlled by server. Returned error represent client-level errors, like failed http call, failed marshaling and so on.

type HandlersGroup

type HandlersGroup map[string]ServerFn

HandlersGroup alias for map of handlers

type L

type L interface {
	Logf(format string, args ...interface{})
}

L defined logger interface used for an optional rest logging

type LoggerFunc

type LoggerFunc func(format string, args ...interface{})

LoggerFunc type is an adapter to allow the use of ordinary functions as Logger.

func (LoggerFunc) Logf

func (f LoggerFunc) Logf(format string, args ...interface{})

Logf calls f(id)

type Option added in v0.3.0

type Option func(s *Server)

Option func type

func Auth added in v0.3.0

func Auth(user, password string) Option

Auth sets basic auth credentials, required

func WithLimits added in v0.3.0

func WithLimits(limit float64) Option

WithLimits sets value for client limit call/sec per client middleware

func WithLogger added in v0.3.0

func WithLogger(logger L) Option

WithLogger sets custom logger, optional

func WithMiddlewares added in v0.3.0

func WithMiddlewares(middlewares ...func(http.Handler) http.Handler) Option

WithMiddlewares sets custom middlewares list, optional

func WithSignature added in v0.3.0

func WithSignature(appName, author, version string) Option

WithSignature sets signature data for server response headers

func WithThrottler added in v0.3.0

func WithThrottler(limit int) Option

WithThrottler sets throttler middleware with specify limit value, optional

func WithTimeouts added in v0.3.0

func WithTimeouts(timeouts Timeouts) Option

WithTimeouts sets server timeout values such as ReadHeader, Write and Idle timeout, optional. If this option not defined server use default timeout values

type Request

type Request struct {
	Method string      `json:"method"`           // method (function) name
	Params interface{} `json:"params,omitempty"` // function arguments
	ID     uint64      `json:"id"`               // unique call id
}

Request encloses method name and all params

type Response

type Response struct {
	Result *json.RawMessage `json:"result,omitempty"` // response json
	Error  string           `json:"error,omitempty"`  // optional remote (server side / plugin side) error
	ID     uint64           `json:"id"`               // unique call id, echoed Request.ID to allow calls tracing
}

Response encloses result and error received from remote server

func EncodeResponse

func EncodeResponse(id uint64, resp interface{}, e error) Response

EncodeResponse convert anything (type interface{}) and incoming error (if any) to Response

type Server

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

Server is json-rpc server with an optional basic auth

func NewServer added in v0.3.0

func NewServer(api string, options ...Option) *Server

NewServer the main constructor of server instance which pass API url and another options values

func (*Server) Add

func (s *Server) Add(method string, fn ServerFn)

Add method handler. Handler will be called on matching method (Request.Method)

func (*Server) Group

func (s *Server) Group(prefix string, m HandlersGroup)

Group of handlers with common prefix, match on group.method

func (*Server) Run

func (s *Server) Run(port int) error

Run http server on given port

func (*Server) Shutdown

func (s *Server) Shutdown() error

Shutdown http server

type ServerFn

type ServerFn func(id uint64, params json.RawMessage) Response

ServerFn handler registered for each method with Add or Group. Implementations provided by consumer and defines response logic.

type Timeouts added in v0.3.0

type Timeouts struct {
	ReadHeaderTimeout time.Duration // amount of time allowed to read request headers
	WriteTimeout      time.Duration // max duration before timing out writes of the response
	IdleTimeout       time.Duration // max amount of time to wait for the next request when keep-alive enabled
	CallTimeout       time.Duration // max time allowed to finish the call, optional
}

Timeouts includes values and timeouts for the server

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL