RPC interface
Let's begin connecting dchat up to JSON-RPC using DarkFi's rpc module.
We'll start by defining a new struct called JsonRpcInterface
that
takes two values, an accept Url
that will receive JSON-RPC requests,
and a pointer to the p2p network.
pub struct JsonRpcInterface {
pub addr: Url,
pub p2p: net::P2pPtr,
}
We'll need to implement a trait called RequestHandler
for
the JsonRpcInterface
. RequestHandler
exposes a method called
handle_request()
which is a handle for processing incoming
JSON-RPC requests. handle_request()
takes a JsonRequest
and returns a JsonResult
. These types are defined inside
jsonrpc.rs
This is JsonResult
:
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum JsonResult {
Response(JsonResponse),
Error(JsonError),
Notification(JsonNotification),
Subscriber(JsonSubscriber),
}
This is JsonRequest
:
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct JsonRequest {
/// JSON-RPC version
pub jsonrpc: Value,
/// Request ID
pub id: Value,
/// Request method
pub method: Value,
/// Request parameters
pub params: Value,
}
We'll use handle_request()
to run a match statement on
JsonRequest.method
.
Running a match on method
will allow us to branch out to functions
that respond to methods received over JSON-RPC. We haven't implemented
any methods yet, so for now let's just return a JsonError
.
#[async_trait]
impl RequestHandler for JsonRpcInterface {
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
if req.params.as_array().is_none() {
return JsonError::new(ErrorCode::InvalidRequest, None, req.id).into()
}
debug!(target: "RPC", "--> {}", serde_json::to_string(&req).unwrap());
match req.method.as_str() {
Some(_) | None => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
}
}
}