Skip to content

Conversation

@blainsmith
Copy link

This is just a first pass at adding a jsonrpc package under http as a transport. I haven't written tests yet, since I wanted to gather feedback as to whether this was in the spirit of gokit before continuing along. Feel free to rip it apart and let me know how it looks.

This was a awesome learning experience too!

@willfaught
Copy link
Contributor

In general, is jsonrpc tied to HTTP or can it be done over raw TCP too? If so, it'd be nice to have that option.

@blainsmith
Copy link
Author

In general, no it isn't. Technically HTTP is the transport and JSON RPC is the codec. To abstract this even more RPC is is the codec and JSON is the data format, you could have XML :trollface: or anything else if there was an interface defined for it.

I started down that route, but pulled back since I didn't want to get too deep into the rabbit hole before involving maintainers.

@willfaught
Copy link
Contributor

willfaught commented Feb 7, 2017 via email

@peterbourgon
Copy link
Member

I've never heard of anyone doing JSON/RPC over anything other than HTTP, I wouldn't put that up as a blocker.

@blainsmith
Copy link
Author

Yes it does, however it does not provide the convenience structs for doing it over HTTP POST methods. It serves over HTTP, but requires the CONNECT method to process the request.

The stdlib does't expose the proper request and response object either, especially for decoding/encoding to JSON with struct tags.

JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params json.RawMessage `json:"params"`
ID interface{} `json:"id"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of interface{}, the ID could be a custom type that implements MarshalJSON. Thoughts?


// Decode the body into an object
var req Request
err := json.NewDecoder(r.Body).Decode(&req)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit troubling that there is no way to wrap the r.Body by another io.Reader here. For example someone might want to wrap it with a io.LimitReader to ensure that the server is not flooded with a stream of neverending bytes.

Perhaps a ServerOption can be added here.


res.Result = resParams

json.NewEncoder(w).Encode(res)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the Decode, but here my request would be to be able to set options on the encoder: Example to pretty print the response, I'd want to SetIndent

@blainsmith
Copy link
Author

@groob Thanks for the feedback here. I appreciate it. I will spend more time cleaning up these parts and update the PR.

@peterbourgon
Copy link
Member

Just wanted to make it clear I'm +1 on this package existing, and the general direction looks good to me. I'll withhold further review until you get it into a more final state. JSON/RPC is new to me, I'd love to see a comprehensive example as part of the PR.

@basvanbeek
Copy link
Member

I would like to see if we can extend the transport's logic to include RPC batch support which is part of the JSON-RPC 2.0 spec.

The spec is very friendly in that it is explicit about not enforcing any guarantees in parallelism or response order sequence so having this feature in should not be terribly difficult.

@blainsmith
Copy link
Author

@basvanbeek Yes, supporting the full spec should be trivial. I wanted to get the basics ironed out first since expanding it for batching and notifications should be simple.

This was referenced Jul 17, 2017
@peterbourgon
Copy link
Member

Closing in favor of #576

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants