jsonrpc

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2021 License: MIT Imports: 4 Imported by: 0

README

jsonrpc-lite

PkgGoDev Build Status codecov Go Report Card GitHub release license

Parse and Serialize JSON-RPC2 messages in golang

https://www.jsonrpc.org/specification

Interface Inspired by https://github.com/teambition/jsonrpc-lite

ID Fork from golang.org/x/tools/internal/jsonrpc2@feee8acb394c170fe9eb4eb9f538b8877d9a3cd4

Features

  • No depend
  • Only Parse and Serialize JSON-RPC2 messages
  • No net.Conn, http, websocket control, You can use any protocol
  • Support batch

Examples

package main

import (
	"fmt"
	"github.com/SB-IM/jsonrpc-lite"
)

func main() {
	recv := []byte(`
	{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
	`)

	fmt.Printf("Server RECV: %s\n", recv)
	rpc := jsonrpc.ParseObject(recv)
	if rpc.Type != jsonrpc.TypeRequest {
		panic("Not jsonrpc.TypeRequest")
	}

	send, err := jsonrpc.NewSuccess(rpc.ID, rpc).ToJSON()
	if err != nil {
		panic(err)
	}
	fmt.Printf("Server SEND: %s\n", send)
}
Recv
// alone
rpc := jsonrpc.ParseObject([]byte(`
{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}`
))

if rpc.Type != jsonrpc.TypeRequest {
	fmt.Println(rpc)
}


// Batch
rpcs := jsonrpc.Batch([]byte(`
[
	{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
	{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
	{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
	{"foo": "boo"},
	{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
	{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
]
`))

for i, rpc := range rpcs {
	fmt.Println(i, rpc)
}
Request
data, err := jsonrpc.NewRequest("123", "test", []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Notify
data, err := jsonrpc.NewNotify("test", []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Success
data, err := jsonrpc.NewSuccess(1234, []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Error

Custom error

// NewError
data, err := jsonrpc.NewError(233, 1, "This is Error", []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Errors

The error codes from and including -32768 to -32000 are reserved for pre-defined error

// NewErrors
res := jsonrpc.NewErrors(1234)
res.Errors.ParseError([]string{"data", "data2"})
data, err := res.ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)

TODO

Documentation

Index

Examples

Constants

View Source
const (
	// CodeParseError is used when invalid JSON was received by the server.
	CodeParseError    = -32700
	MessageParseError = "Parse error"
	//CodeInvalidRequest is used when the JSON sent is not a valid Request object.
	CodeInvalidRequest    = -32600
	MessageInvalidRequest = "Invalid Request"
	// CodeMethodNotFound should be returned by the handler when the method does
	// not exist / is not available.
	CodeMethodNotFound    = -32601
	MessageMethodNotFound = "Method not found"
	// CodeInvalidParams should be returned by the handler when method
	// parameter(s) were invalid.
	CodeInvalidParams    = -32602
	MessageInvalidParams = "Invalid params"
	// CodeInternalError is not currently returned but defined for completeness.
	CodeInternalError    = -32603
	MessageInternalError = "Internal error"
)
View Source
const (
	// Internal inference error, default
	TypeInvalid = iota
	// Request object
	TypeRequest
	// Response object result
	TypeSuccess
	// Notification
	TypeNotify
	// Response object error
	TypeErrors
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Errors

type Errors 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"`
}

Error represents a structured error in a Response.

func (*Errors) Error

func (err *Errors) Error() string

func (*Errors) InternalError

func (e *Errors) InternalError(data interface{})

Set Errors InternalError

func (*Errors) InvalidParams

func (e *Errors) InvalidParams(data interface{})

Set Errors InvalidParams

func (*Errors) InvalidRequest

func (e *Errors) InvalidRequest(data interface{})

Set Errors InvalidRequest

func (*Errors) MethodNotFound

func (e *Errors) MethodNotFound(data interface{})

Set Errors MethodNotFound

func (*Errors) ParseError

func (e *Errors) ParseError(data interface{})

Set Errors ParseError

type ID

type ID struct {
	Name   string
	Number int64
}

ID is a Request identifier. Only one of either the Name or Number members will be set, using the number form if the Name is the empty string.

func NewID

func NewID(raw interface{}) (id *ID)

int(8, 16, 32, 64), string, *ID, ID Other type to (string): fmt.Sprint

func (*ID) MarshalJSON

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

func (*ID) String

func (id *ID) String() string

String returns a string representation of the ID. The representation is non ambiguous, string forms are quoted, number forms are preceded by a #

func (*ID) UnmarshalJSON

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

type Jsonrpc

type Jsonrpc struct {
	Type int `json:"-"`
	// VersionTag is always encoded as the string "2.0"
	VersionTag VersionTag `json:"jsonrpc"`
	// Method is a string containing the method name to invoke.
	Method string `json:"method,omitempty"`
	// Params is either a struct or an array with the parameters of the method.
	Params *json.RawMessage `json:"params,omitempty"`
	// Result is the response value, and is required on success.
	Result *json.RawMessage `json:"result,omitempty"`
	// Error is a structured error response if the call fails.
	Errors *Errors `json:"error,omitempty"`
	// The id of this request, used to tie the Response back to the request.
	// Will be either a string or a number. If not set, the Request is a notify,
	// and no response is possible.
	ID *ID `json:"id,omitempty"`
}

combined has all the fields of both Request and Response. We can decode this and then work out which it is.

func Batch

func Batch(raw []byte) []*Jsonrpc

Batch ParseObject if Parse error len == 0

Example
rpcs := jsonrpc.Batch([]byte(`
	[
		{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
		{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
		{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
		{"foo": "boo"},
		{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
		{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
	]
	`))

for i, rpc := range rpcs {
	fmt.Println(i, rpc)
}
Output:

func NewError

func NewError(id interface{}, code int64, message string, data interface{}) *Jsonrpc

New Response error

func NewErrors

func NewErrors(id interface{}) *Jsonrpc

New a Null Error NewErrors(1234).Error.MethodNotFound("233").ToJSON()

Example
res := jsonrpc.NewErrors(1234)
res.Errors.ParseError([]string{"data", "data2"})
data, err := res.ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Output:

func NewNotify

func NewNotify(method string, params interface{}) *Jsonrpc

New Notification, No ID

func NewRequest

func NewRequest(id interface{}, method string, params interface{}) *Jsonrpc

New Request

Example
data, err := jsonrpc.NewRequest("123", "test", []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Output:

func NewSuccess

func NewSuccess(id, result interface{}) *Jsonrpc

New Response result

Example
data, err := jsonrpc.NewSuccess(1234, []string{"sss", "zzz"}).ToJSON()
if err != nil {
	panic(err)
}
fmt.Printf("%s\n", data)
Output:

func Parse

func Parse(raw []byte) (*Jsonrpc, error)

Parse message to jsonrpc

Example
rpc, err := jsonrpc.Parse([]byte(`
	{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
	`))
if err != nil {
	panic(err)
}

if rpc.Type != jsonrpc.TypeRequest {
	fmt.Println(rpc)
}
fmt.Println(rpc)
Output:

func ParseObject

func ParseObject(raw []byte) *Jsonrpc

Ignore the parse error

Example
rpc := jsonrpc.ParseObject([]byte(`
	{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
	`))
if rpc.Type != jsonrpc.TypeRequest {
	fmt.Println(rpc)
}
fmt.Println(rpc)
Output:

func (*Jsonrpc) ToJSON

func (t *Jsonrpc) ToJSON() ([]byte, error)

Verification && json.Marshal object

type VersionTag

type VersionTag struct{}

VersionTag is a special 0 sized struct that encodes as the jsonrpc version tag. It will fail during decode if it is not the correct version tag in the stream.

func (VersionTag) MarshalJSON

func (VersionTag) MarshalJSON() ([]byte, error)

func (VersionTag) UnmarshalJSON

func (VersionTag) UnmarshalJSON(data []byte) error

Jump to

Keyboard shortcuts

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