Documentation
¶
Overview ¶
Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. https://www.jsonrpc.org/specification It is intended to be compatible with other implementations at the wire level.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrIdleTimeout is returned when serving timed out waiting for new connections. ErrIdleTimeout = errors.New("timed out waiting for new connections") // ErrNotHandled is returned from a Handler or Preempter to indicate it did // not handle the request. // // If a Handler returns ErrNotHandled, the server replies with // ErrMethodNotFound. ErrNotHandled = errors.New("JSON RPC not handled") // ErrAsyncResponse is returned from a handler to indicate it will generate a // response asynchronously. // // ErrAsyncResponse must not be returned for notifications, // which do not receive responses. ErrAsyncResponse = errors.New("JSON RPC asynchronous response") )
var ( // ErrParse is used when invalid JSON was received by the server. ErrParse = NewError(-32700, "JSON RPC parse error") // ErrInvalidRequest is used when the JSON sent is not a valid Request object. ErrInvalidRequest = NewError(-32600, "JSON RPC invalid request") // ErrMethodNotFound should be returned by the handler when the method does // not exist / is not available. ErrMethodNotFound = NewError(-32601, "JSON RPC method not found") // ErrInvalidParams should be returned by the handler when method // parameter(s) were invalid. ErrInvalidParams = NewError(-32602, "JSON RPC invalid params") // ErrInternal indicates a failure to process a call correctly ErrInternal = NewError(-32603, "JSON RPC internal error") // ErrServerOverloaded is returned when a message was refused due to a // server being temporarily unable to accept any new messages. ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded") // ErrUnknown should be used for all non coded errors. ErrUnknown = NewError(-32001, "JSON RPC unknown error") // ErrServerClosing is returned for calls that arrive while the server is closing. ErrServerClosing = NewError(-32002, "JSON RPC server is closing") // ErrClientClosing is a dummy error returned for calls initiated while the client is closing. ErrClientClosing = NewError(-32003, "JSON RPC client is closing") )
Functions ¶
func EncodeIndent ¶
EncodeIndent is like EncodeMessage, but honors indents. TODO(rfindley): refactor so that this concern is handled independently. Perhaps we should pass in a json.Encoder?
func EncodeMessage ¶
Types ¶
type Framer ¶
type Framer interface {
// Reader wraps a byte reader into a message reader.
Reader(io.Reader) Reader
// Writer wraps a byte writer into a message writer.
Writer(io.Writer) Writer
}
Framer wraps low level byte readers and writers into jsonrpc2 message readers and writers. It is responsible for the framing and encoding of messages into wire form.
TODO(rfindley): rethink the framer interface, as with JSONRPC2 batching there is a need for Reader and Writer to be correlated, and while the implementation of framing here allows that, it is not made explicit by the interface.
Perhaps a better interface would be
Frame(io.ReadWriteCloser) (Reader, Writer).
func HeaderFramer ¶
func HeaderFramer() Framer
HeaderFramer returns a new Framer. The messages are sent with HTTP content length and MIME type headers. This is the format used by LSP and others.
type Handler ¶
type Handler interface {
// Handle is invoked sequentially for each incoming request that has not
// already been handled by a Preempter.
//
// If the Request has a nil ID, Handle must return a nil result,
// and any error may be logged but will not be reported to the caller.
//
// If the Request has a non-nil ID, Handle must return either a
// non-nil, JSON-marshalable result, or a non-nil error.
//
// The Context passed to Handle will be canceled if the
// connection is broken or the request is canceled or completed.
// (If Handle returns ErrAsyncResponse, ctx will remain uncanceled
// until either Cancel or Respond is called for the request's ID.)
Handle(ctx context.Context, req *Request) (result any, err error)
}
Handler handles messages on a connection.
type HandlerFunc ¶
A HandlerFunc implements the Handler interface for a standalone Handle function.
type ID ¶
type ID struct {
// contains filtered or unexported fields
}
ID is a Request identifier, which is defined by the spec to be a string, integer, or null. https://www.jsonrpc.org/specification#request_object
func MakeID ¶
MakeID coerces the given Go value to an ID. The value is assumed to be the default JSON marshaling of a Request identifier -- nil, float64, or string.
Returns an error if the value type was a valid Request ID type.
TODO: ID can't be a json.Marshaler/Unmarshaler, because we want to omitzero. Simplify this package by making ID json serializable once we can rely on omitzero.
type Message ¶
type Message interface {
// contains filtered or unexported methods
}
Message is the interface to all jsonrpc2 message types. They share no common functionality, but are a closed set of concrete types that are allowed to implement this interface. The message types are *Request and *Response.
func DecodeMessage ¶
type Preempter ¶
type Preempter interface {
// Preempt is invoked for each incoming request before it is queued for handling.
//
// If Preempt returns ErrNotHandled, the request will be queued,
// and eventually passed to a Handle call.
//
// Otherwise, the result and error are processed as if returned by Handle.
//
// Preempt must not block. (The Context passed to it is for Values only.)
Preempt(ctx context.Context, req *Request) (result any, err error)
}
Preempter handles messages on a connection before they are queued to the main handler. Primarily this is used for cancel handlers or notifications for which out of order processing is not an issue.
type PreempterFunc ¶
A PreempterFunc implements the Preempter interface for a standalone Preempt function.
type Reader ¶
type Reader interface {
// Read gets the next message from the stream.
Read(context.Context) (Message, error)
}
Reader abstracts the transport mechanics from the JSON RPC protocol. A Conn reads messages from the reader it was provided on construction, and assumes that each call to Read fully transfers a single message, or returns an error. A reader is not safe for concurrent use, it is expected it will be used by a single Conn in a safe manner.
type Request ¶
type Request struct {
// ID of this request, used to tie the Response back to the request.
// This will be nil for notifications.
ID ID
// Method is a string containing the method name to invoke.
Method string
// Params is either a struct or an array with the parameters of the method.
Params json.RawMessage
}
Request is a Message sent to a peer to request behavior. If it has an ID it is a call, otherwise it is a notification.
func NewNotification ¶
NewNotification constructs a new Notification message for the supplied method and parameters.
type Response ¶
type Response struct {
// result is the content of the response.
Result json.RawMessage
// err is set only if the call failed.
Error error
// id of the request this is a response to.
ID ID
}
Response is a Message used as a reply to a call Request. It will have the same ID as the call it is a response to.
type WireError ¶
type WireError struct {
// Code is an error code indicating the type of failure.
Code int64 `json:"code"`
// Message is a short description of the error.
Message string `json:"message"`
// Data is optional structured data containing additional information about the error.
Data json.RawMessage `json:"data,omitempty"`
}
WireError represents a structured error in a Response.
type Writer ¶
type Writer interface {
// Write sends a message to the stream.
Write(context.Context, Message) error
}
Writer abstracts the transport mechanics from the JSON RPC protocol. A Conn writes messages using the writer it was provided on construction, and assumes that each call to Write fully transfers a single message, or returns an error. A writer is not safe for concurrent use, it is expected it will be used by a single Conn in a safe manner.