2 stable releases

1.1.0 Oct 13, 2023
1.0.0 May 11, 2023

#2 in #casper


Used in casper-node

Apache-2.0

82KB
1.5K SLoC

casper-json-rpc

LOGO

Build Status Crates.io Documentation License

A library suitable for use as the framework for a JSON-RPC server.

Usage

Normally usage will involve two steps:

Example

use casper_json_rpc::{Error, Params, RequestHandlersBuilder};
use std::{convert::Infallible, sync::Arc};

async fn get(params: Option<Params>) -> Result<String, Error> {
    // * parse params or return `ReservedErrorCode::InvalidParams` error
    // * handle request and return result
    Ok("got it".to_string())
}

async fn put(params: Option<Params>, other_input: &str) -> Result<String, Error> {
    Ok(other_input.to_string())
}

#[tokio::main]
async fn main() {
    // Register handlers for methods "get" and "put".
    let mut handlers = RequestHandlersBuilder::new();
    handlers.register_handler("get", Arc::new(get));
    let put_handler = move |params| async move { put(params, "other input").await };
    handlers.register_handler("put", Arc::new(put_handler));
    let handlers = handlers.build();

    // Get the new route.
    let path = "rpc";
    let max_body_bytes = 1024;
    let route = casper_json_rpc::route(path, max_body_bytes, handlers);

    // Convert it into a `Service` and run it.
    let make_svc = hyper::service::make_service_fn(move |_| {
        let svc = warp::service(route.clone());
        async move { Ok::<_, Infallible>(svc.clone()) }
    });

    hyper::Server::bind(&([127, 0, 0, 1], 3030).into())
        .serve(make_svc)
        .await
        .unwrap();
}

If this receives a request such as

curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"id","method":"get"}' http://127.0.0.1:3030/rpc

then the server will respond with

{"jsonrpc":"2.0","id":"id","result":"got it"}

Errors

To return a JSON-RPC response indicating an error, use Error::new. Most error conditions which require returning a reserved error are already handled in the provided warp filters. The only exception is ReservedErrorCode::InvalidParams which should be returned by any RPC handler which deems the provided params: Option<Params> to be invalid for any reason.

Generally a set of custom error codes should be provided. These should all implement ErrorCodeT.

Example custom error code

use serde::{Deserialize, Serialize};
use casper_json_rpc::ErrorCodeT;

#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
#[repr(i64)]
pub enum ErrorCode {
    /// The requested item was not found.
    NoSuchItem = -1,
    /// Failed to put the requested item to storage.
    FailedToPutItem = -2,
}

impl From<ErrorCode> for (i64, &'static str) {
    fn from(error_code: ErrorCode) -> Self {
        match error_code {
            ErrorCode::NoSuchItem => (error_code as i64, "No such item"),
            ErrorCode::FailedToPutItem => (error_code as i64, "Failed to put item"),
        }
    }
}

impl ErrorCodeT for ErrorCode {}

License

Licensed under the Apache License Version 2.0.

Dependencies

~9–19MB
~254K SLoC