jsonrpc2

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2025 License: MIT Imports: 12 Imported by: 1

README

Go JSON-RPC 2.0

Go Reference

A super easy JSON-RPC 2.0 client and server library for Go.

Example

Server
package main

import (
	"context"
	"log"

	"github.com/macrat/go-jsonrpc2"
)

func main() {
	server := jsonrpc2.NewServer()

	// Add a method.
	server.On("sum", jsonrpc2.Call(func(ctx context.Context, xs []int) (int, error) {
		sum := 0
		for _, x := range xs {
			sum += x
		}
		return sum, nil
	}))

	// Add a notification handler.
	server.On("notify", jsonrpc2.Notify(func(ctx context.Context, message string) error {
		log.Printf("notify: %s", message)
		return nil
	}))

	l, err := jsonrpc2.NewTCPListener(":1234")
	if err != nil {
		log.Fatal(err)
	}

	log.Fatal(server.Serve(l))
}
Client
package main

import (
	"context"
	"net"

	"github.com/macrat/go-jsonrpc2"
)

func main() {
	conn, err := net.Dial("tcp", "localhost:1234")
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()

	client := jsonrpc2.NewClient(conn)

	// Call	`sum` method.
	var sum int
	err := client.Call(ctx, "sum", []int{1, 2, 3}, &sum)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("sum: %d", sum)

	// Send `notify` notification.
	err = client.Notify(ctx, "notify", "Hello, World!")
	if err != nil {
		log.Fatal(err)
	}
}

Documentation

Overview

jsonrpc2 is a super easy JSON-RPC 2.0 client and server library.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidID     = errors.New("Invalid ID")
	ErrInvalidIDType = fmt.Errorf("%w: %w", ErrInvalidID, errors.New("ID have to be either integer, string, or null"))
)
View Source
var (
	ErrParseError     = Error{Code: ParseErrorCode, Message: "Parse error"}
	ErrInvalidRequest = Error{Code: InvalidRequestCode, Message: "Invalid Request"}
	ErrMethodNotFound = Error{Code: MethodNotFoundCode, Message: "Method not found"}
	ErrInvalidParams  = Error{Code: InvalidParamsCode, Message: "Invalid params"}
	ErrInternalError  = Error{Code: InternalErrorCode, Message: "Internal error"}
)
View Source
var (
	ErrInvalidVersion = errors.New(`Invalid version: "jsonrpc" must be exactly "2.0"`)
)

Functions

This section is empty.

Types

type BatchRequest

type BatchRequest struct {
	// Method is the method name to call.
	Method string

	// Params is the parameters to pass to the method.
	Params any

	// IsNotify is true if the request is a notification.
	// If true, the client will not receive a response from the server.
	IsNotify bool
}

BatchRequest is a request for `Client.Batch`.

type BatchResponse

type BatchResponse struct {
	// Method is the method name that was called.
	Method string

	// Params is the parameters that were passed to the method.
	Params any

	// Result is the result of the method call.
	// Please use json.Unmarshal to read it.
	Result json.RawMessage

	// Error is the error that reported by the server.
	Error *Error
}

BatchResponse is a response from `Client.Batch`.

type Client

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

Client is a JSON-RPC 2.0 client.

func NewClient

func NewClient(rw io.ReadWriter) *Client

NewClient creates a new JSON-RPC 2.0 client.

The `rw` parameter is the read-writer to communicate with the server.

This function starts a goroutine to read responses from the server. Please make sure to call `Close` to stop the goroutine when you are done.

func (*Client) Batch

func (c *Client) Batch(ctx context.Context, reqs []BatchRequest) ([]*BatchResponse, error)

Batch sends multiple requests to the server at once.

func (*Client) Call

func (c *Client) Call(ctx context.Context, name string, params any, result any) error

Call calls a method on the server.

The response from the server is unmarshaled into the `result` parameter. If you do not need the response, use `Notify` instead.

func (*Client) Close

func (c *Client) Close() error

Close stops the client.

A client cannot be used after it is closed.

func (*Client) Notify

func (c *Client) Notify(ctx context.Context, name string, params any) error

Notify sends a notification to the server.

Even if the server replies something, the client will not receive it. If you need the response, use `Call` instead.

type Error

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

Error represents a JSON-RPC 2.0 error object.

This struct can be used as `error` value. The server uses this value if handlers return it as an error.

func (Error) Error

func (e Error) Error() string

type ErrorCode

type ErrorCode int64
const (
	ParseErrorCode     ErrorCode = -32700
	InvalidRequestCode ErrorCode = -32600
	MethodNotFoundCode ErrorCode = -32601
	InvalidParamsCode  ErrorCode = -32602
	InternalErrorCode  ErrorCode = -32603
)

func (ErrorCode) String

func (e ErrorCode) String() string

type Handler

type Handler interface {
	ServeJSONRPC2(context.Context, RawRequest) (any, error)
}

Handler is a base interface for JSON-RPC 2.0 handlers.

In almost all cases, you do not need to implement this interface directly. Please use jsonrpc2.Call or jsonrpc2.Notify to create a handler.

func Call

func Call[I, O any](f func(context.Context, I) (O, error)) Handler

Call creates a new JSON-RPC 2.0 handler for a method that returns a result.

func Notify

func Notify[I any](f func(context.Context, I) error) Handler

Notify creates a new JSON-RPC 2.0 handler for a method that does not return a result.

type ID

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

ID respesents ID in JSON-RPC 2.0 request/response.

func Int64ID

func Int64ID(i int64) *ID

Int64ID creates a new ID with int64 value.

func NullID

func NullID() *ID

NullID creates a new ID with null value.

This value is used for error response. Please use normal nil value for notification.

func StringID

func StringID(s string) *ID

StringID creates a new ID with string value.

func (ID) MarshalJSON

func (id ID) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler interface.

func (ID) Raw

func (id ID) Raw() any

Raw returns raw ID value in int64, string, or nil.

func (ID) String

func (id ID) String() string

String returns string representation of ID.

func (*ID) UnmarshalJSON

func (id *ID) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler interface.

type Listener

type Listener interface {
	Accept() (io.ReadWriter, error)
	Close() error
}

Listener is an interface for accepting connections.

This interface is used for `Server.Serve` method.

func NewTCPListener

func NewTCPListener(addr string) (Listener, error)

NewTCPListener creates a new Listener for TCP connections.

func NewUnixListener

func NewUnixListener(addr string) (Listener, error)

NewUnixListener creates a new Listener for Unix domain socket connections.

type RawRequest

type RawRequest = Request[json.RawMessage]

RawRequest is a variant of `Request` that uses `json.RawMessage` for `Params`.

This type is used for handling requests in `Server`.

type Request

type Request[T any] struct {
	Jsonrpc Version `json:"jsonrpc"`
	Method  string  `json:"method"`
	Params  T       `json:"params,omitempty"`
	ID      *ID     `json:"id,omitempty"`
}

Request represents a JSON-RPC 2.0 request.

You usually do not need to use this struct directly. Please use `Client.Call` or `Client.Notify` method.

func NewRequest

func NewRequest[T any](id *ID, method string, params T) *Request[T]

NewRequest creates a new JSON-RPC 2.0 request.

func (*Request[T]) WriteTo

func (r *Request[T]) WriteTo(w io.Writer) (int64, error)

WriteTo writes JSON-RPC 2.0 request to `io.Writer`.

type Response

type Response[T any] struct {
	Jsonrpc Version `json:"jsonrpc"`
	Result  T       `json:"result,omitempty"`
	Error   *Error  `json:"error,omitempty"`
	ID      *ID     `json:"id"`
}

Response represents a JSON-RPC 2.0 response.

You usually do not need to use this struct directly.

func NewErrorResponse

func NewErrorResponse(id *ID, err Error) *Response[any]

NewErrorResponse creates a new JSON-RPC 2.0 error response.

func NewSuccessResponse

func NewSuccessResponse[T any](id *ID, result T) *Response[T]

NewSuccessResponse creates a new JSON-RPC 2.0 success response.

func (*Response[T]) WriteTo

func (r *Response[T]) WriteTo(w io.Writer) (int64, error)

WriteTo writes JSON-RPC 2.0 response to `io.Writer`.

type Server

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

Server is a JSON-RPC 2.0 server.

func NewServer

func NewServer(opts ...ServerOption) *Server

NewServer creates a new JSON-RPC 2.0 server.

func (*Server) On

func (s *Server) On(name string, m Handler)

On registers a new handler for a method.

If the handler returns `Error` struct as an error, the server sends an error as-is to the client.

func (*Server) Serve

func (s *Server) Serve(l Listener) error

Serve accepts connections from the given listener and handles them.

func (*Server) ServeForOne

func (s *Server) ServeForOne(rw io.ReadWriter)

ServeForOne reads requests from the given io.ReadWriter and sends responses to it.

func (*Server) ServeHTTP added in v0.2.0

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler interface.

func (*Server) ServeJSONRPC2

func (s *Server) ServeJSONRPC2(ctx context.Context, r RawRequest) (any, error)

ServeJSONRPC2 implements the Handler interface.

Do not call this method directly.

type ServerOption

type ServerOption func(*Server)

ServerOption is a type for server options.

func WithMaxConcurrentCalls

func WithMaxConcurrentCalls(maxConcurrent int) ServerOption

WithMaxConcurrentCalls specifies the maximum number of concurrent calls the server can handle. If this option is not specified, the default value is 100.

maxConcurrent must be greater than 0.

type Version

type Version string

Version represents "jsonrpc" value in JSON-RPC 2.0 request/response. This value is always "2.0".

const VersionValue Version = "2.0"

func (*Version) UnmarshalJSON

func (v *Version) UnmarshalJSON(data []byte) error

Jump to

Keyboard shortcuts

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