Documentation
¶
Overview ¶
Package jsonrpc helps JSON-RPC 2.0 implements.
Index ¶
- Constants
- func MethodName(c context.Context) string
- func ParseRequest(r *http.Request) ([]*Request, bool, *Error)
- func RequestID(c context.Context) *json.RawMessage
- func SendResponse(w http.ResponseWriter, resp []*Response, batch bool) error
- func WithMetadata(c context.Context, md Metadata) context.Context
- func WithMethodName(c context.Context, name string) context.Context
- func WithRequestID(c context.Context, id *json.RawMessage) context.Context
- type Error
- type ErrorCode
- type Handler
- type HandlerFunc
- type Metadata
- type MethodReference
- type MethodRepository
- func (mr *MethodRepository) InvokeMethod(c context.Context, r *Request) *Response
- func (mr *MethodRepository) Methods() map[string]Metadata
- func (mr *MethodRepository) RegisterMethod(method string, h Handler, params, result any) error
- func (mr *MethodRepository) ServeDebug(w http.ResponseWriter, r *http.Request)
- func (mr *MethodRepository) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (mr *MethodRepository) TakeMethod(r *Request) (Handler, *Error)
- func (mr *MethodRepository) TakeMethodMetadata(r *Request) (Metadata, *Error)
- type Request
- type Response
Examples ¶
Constants ¶
const (
// Version is JSON-RPC 2.0.
Version = "2.0"
)
Variables ¶
This section is empty.
Functions ¶
func MethodName ¶
MethodName takes method name from context.
func ParseRequest ¶
ParseRequest parses a HTTP request to JSON-RPC request.
func RequestID ¶
func RequestID(c context.Context) *json.RawMessage
RequestID takes request id from context.
func SendResponse ¶
func SendResponse(w http.ResponseWriter, resp []*Response, batch bool) error
SendResponse writes JSON-RPC response.
func WithMetadata ¶
WithMetadata adds jsonrpc metadata to context.
func WithMethodName ¶
WithMethodName adds method name to context.
func WithRequestID ¶
WithRequestID adds request id to context.
Types ¶
type Error ¶
type Error struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
An Error is a wrapper for a JSON interface value.
func ErrInvalidParams ¶
func ErrInvalidParams() *Error
ErrInvalidParams returns invalid params error.
func ErrInvalidRequest ¶
func ErrInvalidRequest() *Error
ErrInvalidRequest returns invalid request error.
func ErrMethodNotFound ¶
func ErrMethodNotFound() *Error
ErrMethodNotFound returns method not found error.
type ErrorCode ¶
type ErrorCode int
A ErrorCode by JSON-RPC 2.0.
const ( // ErrorCodeParse is parse error code. ErrorCodeParse ErrorCode = -32700 // ErrorCodeInvalidRequest is invalid request error code. ErrorCodeInvalidRequest ErrorCode = -32600 // ErrorCodeMethodNotFound is method not found error code. ErrorCodeMethodNotFound ErrorCode = -32601 // ErrorCodeInvalidParams is invalid params error code. ErrorCodeInvalidParams ErrorCode = -32602 // ErrorCodeInternal is internal error code. ErrorCodeInternal ErrorCode = -32603 )
type Handler ¶
type Handler interface {
ServeJSONRPC(c context.Context, params *json.RawMessage) (result any, err *Error)
}
Handler links a method of JSON-RPC request.
type HandlerFunc ¶
HandlerFunc type is an adapter to allow the use of ordinary functions as JSONRPC handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a jsonrpc.Handler that calls f.
func (HandlerFunc) ServeJSONRPC ¶
func (f HandlerFunc) ServeJSONRPC(c context.Context, params *json.RawMessage) (any, *Error)
ServeJSONRPC calls f(w, r).
type Metadata ¶
Metadata has method meta data.
func GetMetadata ¶
GetMetadata takes jsonrpc metadata from context.
type MethodReference ¶
type MethodReference struct {
Name string `json:"name"`
Handler string `json:"handler"`
Params *jsonschema.Schema `json:"params,omitempty"`
Result *jsonschema.Schema `json:"result,omitempty"`
}
A MethodReference is a reference of JSON-RPC method.
type MethodRepository ¶
type MethodRepository struct {
// contains filtered or unexported fields
}
A MethodRepository has JSON-RPC method functions.
func NewMethodRepository ¶
func NewMethodRepository() *MethodRepository
NewMethodRepository returns new MethodRepository.
func (*MethodRepository) InvokeMethod ¶
func (mr *MethodRepository) InvokeMethod(c context.Context, r *Request) *Response
InvokeMethod invokes JSON-RPC method.
func (*MethodRepository) Methods ¶
func (mr *MethodRepository) Methods() map[string]Metadata
Methods returns registered methods.
func (*MethodRepository) RegisterMethod ¶
func (mr *MethodRepository) RegisterMethod(method string, h Handler, params, result any) error
RegisterMethod registers jsonrpc.Func to MethodRepository.
func (*MethodRepository) ServeDebug ¶
func (mr *MethodRepository) ServeDebug(w http.ResponseWriter, r *http.Request)
ServeDebug views registered method list.
func (*MethodRepository) ServeHTTP ¶
func (mr *MethodRepository) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP provides basic JSON-RPC handling.
Example ¶
package main
import (
"bytes"
"context"
"io"
"log"
"net/http"
"net/http/httptest"
"os"
"github.com/goccy/go-json"
"github.com/osamingo/jsonrpc/v2"
)
type (
EchoHandler struct{}
EchoParams struct {
Name string `json:"name"`
}
EchoResult struct {
Message string `json:"message"`
}
PositionalHandler struct{}
PositionalParams []int
PositionalResult struct {
Message []int `json:"message"`
}
)
func (h EchoHandler) ServeJSONRPC(_ context.Context, params *json.RawMessage) (interface{}, *jsonrpc.Error) {
var p EchoParams
if err := jsonrpc.Unmarshal(params, &p); err != nil {
return nil, err
}
return EchoResult{
Message: "Hello, " + p.Name,
}, nil
}
func (h PositionalHandler) ServeJSONRPC(_ context.Context, params *json.RawMessage) (interface{}, *jsonrpc.Error) {
var p PositionalParams
if err := jsonrpc.Unmarshal(params, &p); err != nil {
return nil, err
}
return PositionalResult{
Message: p,
}, nil
}
func main() { //nolint: nosnakecase
mr := jsonrpc.NewMethodRepository()
if err := mr.RegisterMethod("Main.Echo", EchoHandler{}, EchoParams{}, EchoResult{}); err != nil {
log.Println(err)
return
}
if err := mr.RegisterMethod("Main.Positional", PositionalHandler{}, PositionalParams{}, PositionalResult{}); err != nil {
log.Println(err)
return
}
http.Handle("/jrpc", mr)
http.HandleFunc("/jrpc/debug", mr.ServeDebug)
srv := httptest.NewServer(http.DefaultServeMux)
defer srv.Close()
contextType := "application/json"
echoVal := `{
"jsonrpc": "2.0",
"method": "Main.Echo",
"params": {
"name": "John Doe"
},
"id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b"
}`
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, srv.URL+"/jrpc", bytes.NewBufferString(echoVal))
if err != nil {
log.Println(err)
return
}
req.Header.Add("Content-Type", contextType)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Println(err)
return
}
defer resp.Body.Close()
if _, err := io.Copy(os.Stdout, resp.Body); err != nil {
log.Println(err)
return
}
positionalVal := `{
"jsonrpc": "2.0",
"method": "Main.Positional",
"params": [3, 1, 1, 3, 5, 3],
"id": "243a718a-2ebb-4e32-8cc8-210c39e8a14b"
}`
req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, srv.URL+"/jrpc", bytes.NewBufferString(positionalVal))
if err != nil {
log.Println(err)
return
}
req.Header.Add("Content-Type", contextType)
resp, err = http.DefaultClient.Do(req)
if err != nil {
log.Println(err)
return
}
defer resp.Body.Close()
if _, err := io.Copy(os.Stdout, resp.Body); err != nil {
log.Println(err)
return
}
}
Output: {"jsonrpc":"2.0","result":{"message":"Hello, John Doe"},"id":"243a718a-2ebb-4e32-8cc8-210c39e8a14b"} {"jsonrpc":"2.0","result":{"message":[3,1,1,3,5,3]},"id":"243a718a-2ebb-4e32-8cc8-210c39e8a14b"}
func (*MethodRepository) TakeMethod ¶
func (mr *MethodRepository) TakeMethod(r *Request) (Handler, *Error)
TakeMethod takes jsonrpc.Func in MethodRepository.
func (*MethodRepository) TakeMethodMetadata ¶
func (mr *MethodRepository) TakeMethodMetadata(r *Request) (Metadata, *Error)
TakeMethodMetadata takes metadata in MethodRepository for request.
type Request ¶
type Request struct {
Version string `json:"jsonrpc"`
Method string `json:"method"`
Params *json.RawMessage `json:"params"`
ID *json.RawMessage `json:"id"`
}
A Request represents a JSON-RPC request received by the server.
type Response ¶
type Response struct {
Version string `json:"jsonrpc"`
Result any `json:"result,omitempty"`
Error *Error `json:"error,omitempty"`
ID *json.RawMessage `json:"id,omitempty"`
}
A Response represents a JSON-RPC response returned by the server.
func NewResponse ¶
NewResponse generates a JSON-RPC response.