GithubHelp home page GithubHelp logo

jsonrpc's People

Contributors

alex-dodich avatar fnguyen-tc avatar matthiasng avatar mier85 avatar rossmcf avatar sapexoid avatar trey-jones avatar ybbus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsonrpc's Issues

Passing `Id` to request

Hello, I have gone through the project and I still can't figure out how to pass Id to the request

Invalid hardcoded id property in request

Hello.

Currently, RPCClient.CallFor under the hood creates a RPCRequest with (uninitialized) zero .ID property.

This behavior introduces some issues when communicating with services that use other jsonrpc-server libraries.

In my case, I was communicating with NodeJS-based service which uses http-jsonrpc-server package.

When request ID is zero - server just crashes.

I don't know if JSONRPC standard allows zero request ID values and probably I need to address the issue to http-jsonrpc-server package author (sangaman/http-jsonrpc-server#19), but this issue might also affect other jsonrpc server implementations.

Can you please use at least 1 as a default value for requests?

The fix should be pretty simple:

jsonrpc.go:327

func (client *rpcClient) Call(ctx context.Context, method string, params ...interface{}) (*RPCResponse, error) {

   request := &RPCRequest{
+	ID: 1,
   	Method:  method,
   	Params:  Params(params...),
   	JSONRPC: jsonrpcVersion,
   }

   return client.doCall(ctx, request)
}

Result property type in RPCResponse structure. At least for CallFor method.

We have the GetObject method for RPCResponse and here we can find that we do marshal+unmarshal for conversion to custom response structure.

func (RPCResponse *RPCResponse) GetObject(toType interface{}) error {
	js, err := json.Marshal(RPCResponse.Result)
	if err != nil {
		return err
	}

	err = json.Unmarshal(js, toType)
	if err != nil {
		return err
	}

	return nil
}

It could be better if we will use json.RawBytes as a type of Result property.
It means that we will have more efficient code:

func (RPCResponse *RPCResponse) GetObject(toType interface{}) error {
	err = json.Unmarshal(RPCResponse.Result, toType)
	if err != nil {
		return err
	}

	return nil
}

Cannot get latest version: module contains a go.mod file, so module path should be github.com/ybbus/jsonrpc/v2

Background

The github.com/ybbus/jsonrpc uses Go modules and the current release version is v2. And it’s module path is "github.com/ybbus/jsonrpc", instead of "github.com/ybbus/jsonrpc/v2". It must comply with the specification of "Releasing Modules for v2 or higher" available in the Modules documentation. Quoting the specification:

A package that has opted in to modules must include the major version in the import path to import any v2+ modules
To preserve import compatibility, the go command requires that modules with major version v2 or later use a module path with that major version as the final element. For example, version v2.0.0 of example.com/m must instead use module path example.com/m/v2.
https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher

Steps to Reproduce

GO111MODULE=on, run go get targeting any version >= v2.1.3 of the ybbus/jsonrpc:

$ go get github.com/ybbus/[email protected]
go: finding github.com/ybbus/jsonrpc v2.1.5
go: finding github.com/ybbus/jsonrpc v2.1.5
go get github.com/ybbus/[email protected]: github.com/ybbus/[email protected]: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

run go get github.com/ybbus/jsonrpc, the version will stuck in v2.1.2:

$go get github.com/ybbus/jsonrpc
go: downloading github.com/ybbus/jsonrpc v1.1.1
go: downloading github.com/ybbus/jsonrpc v2.1.2+incompatible
go: github.com/ybbus/jsonrpc upgrade => v2.1.2+incompatible 

SO anyone using Go modules will not be able to easily use any newer version of ybbus/jsonrpc.

Solution

1. Kill the go.mod files, rolling back to GOPATH.

This would push them back to not being managed by Go modules (instead of incorrectly using Go modules).
Ensure compatibility for downstream module-aware projects and module-unaware projects projects

2. Fix module path to strictly follow SIV rules.

Patch the go.mod file to declare the module path as github.com/ybbus/jsonrpc/v2 as per the specs. And adjust all internal imports.
The downstream projects might be negatively affected in their building if they are module-unaware (Go versions older than 1.9.7 and 1.10.3; Or use third-party dependency management tools, such as: Dep, glide,govendor…).

[*] You can see who will be affected here: [9 module-unaware users, i.e., ottenwbe/golook, InWeCrypto/keytool, InWeCrypto/wallet-insight]
https://github.com/search?q=ybbus%2Fjsonrpc+filename%3Avendor.conf+filename%3Avendor.json+filename%3Aglide.toml+filename%3AGodep.toml&type=Code

If you don't want to break the above repos. This method can provides better backwards-compatibility.
Release a v2 or higher module through the major subdirectory strategy: Create a new v2 subdirectory (github.com/ybbus/jsonrpc/v2) and place a new go.mod file in that subdirectory. The module path must end with /v2. Copy or move the code into the v2 subdirectory. Update import statements within the module to also use /v2 (import "github.com/ybbus/jsonrpc/v2/…"). Tag the release with v2.x.y.

3. Suggest your downstream module users use hash instead of a version tag.

If the standard rule of go modules conflicts with your development mode. Or not intended to be used as a library and does not make any guarantees about the API. So you can’t comply with the specification of "Releasing Modules for v2 or higher" available in the Modules documentation.
Regardless, since it's against one of the design choices of Go, it'll be a bit of a hack. Instead of go get github.com/ybbus/jsonrpc@version-tag, module users need to use this following way to get the ybbus/jsonrpc:
(1) Search for the tag you want (in browser)
(2) Get the commit hash for the tag you want
(3) Run go get github.com/ybbus/jsonrpc@commit-hash
(4) Edit the go.mod file to put a comment about which version you actually used
This will make it difficult for module users to get and upgrade ybbus/jsonrpc.

[*] You can see who will be affected here: [44 module users, e.g., yuuki0xff/clustertest, zcash-hackworks/eccfaucet, doubtingben/zfaucet]
https://github.com/search?q=ybbus%2Fjsonrpc+filename%3Ago.mod&type=Code

Summary

You can make a choice to fix DM issues by balancing your own development schedules/mode against the affects on the downstream projects.

For this issue, Solution 2 can maximize your benefits and with minimal impacts to your downstream projects the ecosystem.

References

[Enhacement] Additional auth parameter in RPC call

Hi,

is it possible to add an optional auth parameter to the RPC call? For example something that would match this JSON Request:

{
    "jsonrpc": "2.0",
    "method": "do.something",
    "params": {
        "output": [
            "id",
            "name"
        ],
        "interfaces": [
            "id",
            "name"
        ]
    },
    "id": 5,
    "auth": "1234ab123401624291e7d12572075e65"
}

http gzip compress support?

I like your json-rpc library.
Thank you for your efforts.

Could you add http gzip compression support?

sorry for my poor english.

Named parameters

At the moment, only positional parameters are supported. That means function parameters that are provided inside an array in the same order the server / remote function expects them to be.

The other option is to provide parameters as a json object where each parameter is named by a property.
e.g.: {"name": "alex", age: 33}
This is equivalent to positional parameters ["alex", 33] if correct order would be name before age.

Support extensions for request object

Hi, not sure if this is the right place to ask but i'm not sure what else to do.

Is it planned to support custom additional members in the request object?
Specifically i would like to use this jsonrcp client to communicate with Zabbix (Monitoring Software) since it states that it implement an JSONRPC API (https://www.zabbix.com/documentation/4.2/manual/api).

From my point of view this is not true since they require an additional 'auth' member in the request object containing a token which is aquired with the 'user.login' method (https://www.zabbix.com/documentation/4.2/manual/api)

I also found another tool that requires something like that (http://documentation.solarwindsmsp.com/backup/documentation/Content/service-management/json-api/login.htm)

I got no answer from Zabbix via IRC and forum and found some mentions of jsonrpc extensions, but found no further documentation on how these are implemented.

Long story short, is it planned to to support custom member in the request object like there is support for custom headers or a custom http client?

Outdated dependency

Hallo Alexander.

I am using your library and have found that one of the dependencies is outdated.
My IDE shows that there are updates for following package.

github.com/stretchr/testify v1.8.1 -> v1.8.4

If there are no special reasons for not updating the version, it would be great to update them.

I also suggest adding a built-in GitHub feature called "Dependabot" which automatically informs repository owners about available updates. This feature saves me a lot of time for maintaining versions updated.

Danke !

get raw response instead of object

Right now, I'm using

	err = response.GetObject(&variants)
	if err != nil {
		fmt.Printf("get object error: %v\n", err)
		return err
	}

I get a response, but unmarshaling fails - so - if there is any way to get RAW response in JSON format to use a different unmarshaler ?

Batch result should have convenient function to retrieve response by id

Since rpc batch response can be returned in any order, you have to iterate and check ids.
A helper function would be great to find result by id and parse it to the correct object like:

responseList, _ := rpcClient.Batch(req1, req2, req3)

req2IntResponse, _ := responseList.getResponseOf(req2).getInt()

Client requirement to view exceptions

type RPCError struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
}
func (e *RPCError) Error() string {
	return strconv.Itoa(e.Code) + ":" + e.Message
}

Maybe I think data is also necessary for client, because code and message is default and not detail, such as 32000 server error, but data in RPCError contains a more detail message of the exceptions raised by server, it has a good help for client to locate the error precisely. so I prefer to change the code as following:

func (e *RPCError) Error() string {
	data := fmt.Sprintf("%v", e.Data)
	return strconv.Itoa(e.Code) + ":" + e.Message+data
}

Changes in code

Hi ...

First, thanks for a really nice jsonrpc module, it has been quite useful for me. I really like to know what your plans are with this module and if you have any plan for versioning it somehow (not the strongest part of go pkg).

I ran into a situation where some of my code has stopped working as the module changes API, and I like to know if there are more plans for changes in the future ?

[Enhacement] wrap errors with "%w"

Hi
Thanks for your dead simple library. I'm started to using it.
I have a suggestion to improve the error handling.
If you would wrap all errors (especially the once from third party code), this would help to identify errors.
i.e.:

fmt.Errorf("rpc call: bla bla: %w",err)

In my use-case I try to catch the error context.Canceled to ignore it, because I cancel the context on purpose on a clean shutdown of all my goroutines.
If wrapper as in the example above, i could just do:

if errors.Is(err, context.Canceled) {
   // ignore
}

But currently I need to parse the message.

I'm a hobby go dev, but I started also to do this in all potential reusable code to wrap all third-party errors like that and also provide the my own error as variable like the context package to let user of the library use it for the error.Is check:

var Canceled = errors.New("context canceled")

As a reference, here the blog that explains this "feature": https://go.dev/blog/go1.13-errors
Regarding chapter "Whether to Wrap".
My interpretation is to wrap errors if you expose anyway the underlying implementation.
And if you don't expose, it could make sense to create your own errors without wrapping.

So for this case the context package implementation is anyway exposed in jsonrpc. So wrapping would make sense.
For http.Client propably you could hide the implementation as you expose only the interface (not checked very code line, but looks like only the interface is exposed, not the implementation of the client).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.