#json-rpc #json #rpc #serde-json


Simple, robust and pragmatic JSON-RPC 2.0 implementation

32 releases

0.11.1 Mar 15, 2022
0.10.5 Dec 29, 2021
0.10.1 Mar 10, 2021

#1304 in Encoding

Download history 28/week @ 2024-01-08 19/week @ 2024-01-22 7/week @ 2024-02-12 9/week @ 2024-02-19 33/week @ 2024-02-26 19/week @ 2024-03-04 14/week @ 2024-03-11 30/week @ 2024-03-18 7/week @ 2024-03-25 48/week @ 2024-04-01 23/week @ 2024-04-08 72/week @ 2024-04-15

151 downloads per month
Used in 5 crates


564 lines


A simple, pragmatic implementation of JSONRPC-2.0 for Rust that is transport agnostic and adheres strictly to the specification.

Nonblocking support is available using the async feature flag which requires async-trait, see the async example for usage:

cargo run --example hello-world
cargo run --example async

Dual-licensed under MIT and Apache-2.


Simple, robust and pragmatic facade for JSON-RPC2 services that is transport agnostic.

use json_rpc2::*;
use serde_json::Value;

struct ServiceHandler;
impl Service for ServiceHandler {
   type Data = ();
   fn handle(&self, request: &Request, _ctx: &Self::Data) -> Result<Option<Response>> {
       let response = match request.method() {
         "hello" => {
           let params: String = request.deserialize()?;
           let message = format!("Hello, {}!", params);
           Some((request, Value::String(message)).into())
         _ => None

fn main() -> Result<()> {
   let service: Box<dyn Service<Data = ()>> = Box::new(ServiceHandler {});
   let request = Request::new_reply(
       "hello", Some(Value::String("world".to_string())));
   let server = Server::new(vec![&service]);
   let response = server.serve(&request, &());
       Some(Value::String("Hello, world!".to_string())),


When converting from incoming payloads use the from_* functions to convert JSON to a Request so that errors are mapped correctly.


For most applications user data can be assigned to the struct that implements the Service trait but sometimes you may need to serve requests from a callback function that passes useful information you want to expose to the service methods. Use Data = T with a custom type to expose user data to your handlers that is not available when the services are created.


For nonblocking support enable the async feature and use the Service trait from the futures module. You will also need to depend upon the async-trait crate and use the #[async_trait] attribute macro on your service implementation.

See the async example for usage.


~38K SLoC