如何基于Rust jsonrpc crate实现支持命名参数的JSON-RPC服务端?
替代方案推荐
给你几个可行的方案,解决jsonrpc-derive的限制和手动转换的繁琐低效问题:
1. 自定义参数解析Trait,避免重复序列化
自己实现一个轻量的Trait,直接把Params::Map转换成你的参数结构体,省去先序列化再反序列化的冗余步骤:
use jsonrpc_core::{Params, Error}; use serde::de::DeserializeOwned; use serde_json::Value; // 定义Trait,统一处理Params到结构体的转换 pub trait FromParams: DeserializeOwned { fn from_params(params: Params) -> Result<Self, Error> { match params { Params::Map(map) => { // 直接把Map转成Value,再反序列化为目标结构体 let value = Value::Object(map); serde_json::from_value(value) .map_err(|e| Error::invalid_params(e.to_string())) } Params::Array(_) => Err(Error::invalid_params("需要命名参数(对象类型)".into())), Params::None => { serde_json::from_value(Value::Null) .map_err(|e| Error::invalid_params(e.to_string())) } } } } // 给你的参数结构体实现这个Trait #[derive(Debug, serde::Deserialize)] struct UserInfoParams { username: String, email: Option<String>, age: u32, } impl FromParams for UserInfoParams {}
之后在添加方法时直接调用这个Trait的方法,代码简洁且高效:
server.add_method("get_user_info", |params: Params| async move { let args = UserInfoParams::from_params(params)?; // 这里写你的业务逻辑 Ok(jsonrpc_core::Value::String(format!("用户{},年龄{}", args.username, args.age))) });
2. 换用更灵活的JSON-RPC框架:jsonrpsee
如果可以更换框架,jsonrpsee对命名参数的支持更友好,完全符合你想要的API美观性——不需要用结构体包裹所有参数,直接在方法定义中声明单个参数,框架会自动把请求中的命名参数映射到对应位置:
use jsonrpsee::proc_macros::rpc; use jsonrpsee::core::RpcResult; // 定义RPC接口 #[rpc(server)] pub trait UserApi { #[method(name = "get_user_info")] async fn get_user_info(&self, username: String, age: u32, email: Option<String>) -> RpcResult<String>; } // 实现接口逻辑 struct UserRpcServer; impl UserApi for UserRpcServer { async fn get_user_info(&self, username: String, age: u32, email: Option<String>) -> RpcResult<String> { let email_str = email.unwrap_or("未提供".to_string()); Ok(format!("用户{},年龄{},邮箱{}", username, age, email_str)) } }
这个框架底层处理更高效,而且API定义更直观,完全满足按名称传参的需求。
3. 定制jsonrpc-derive(进阶方案)
如果必须坚持使用jsonrpc-derive,可以fork这个crate,修改它的proc-macro代码生成逻辑,让它支持将结构体字段直接映射为命名参数,而不是把整个结构体作为唯一参数。不过这个方案需要你熟悉Rust的proc-macro开发,适合有深度定制需求的场景。
内容的提问来源于stack exchange,提问作者ababo
相关产品推荐
相关产品推荐

