4个版本
0.1.6 | 2024年7月14日 |
---|---|
0.1.5 | 2022年11月27日 |
0.1.3 | 2022年10月30日 |
0.1.0 |
|
#86 在 #client-side
924 每月下载次数
在 20 个crate中使用(通过 nanorpc)
13KB
213 行
nanorpc:JSON-RPC 2.0子集的魔法库(进行中)
动机
通常,编写客户端-服务器网络API(例如,REST API)涉及以下三个步骤
- 用英语指定协议
- 实现协议的服务器端
- 分别实现协议的客户端
这很麻烦且容易出错。协议实际上在三个不同的地方以三种不同的方式指定了三次,保持它们同步是一项巨大的工作。
相反,我们希望一次指定协议,然后自动生成
- 服务器实现,泛型覆盖
- 每个端点的业务逻辑
- 低级网络细节(例如,“在HTTP端点监听”)
- 客户端实现,泛型覆盖低级网络细节(例如,“调用此HTTP端点”)
- 充分利用Rust的类型系统,以帮助避免序列化和反序列化不匹配、拼写错误等问题。
关于 nanorpc
nanorpc
正好做到了这一点。它是一个带有宏 #[nanorpc_derive]
的 JSON-RPC 子集实现,它根据表示API接口的trait,抽象掉了实现API的所有 重复 部分。
特别是
nanorpc
定义了动态类型的JSON-RPC服务器和客户端trait- a trait
RpcService
描述了JSON-RPC服务器端响应者(给定JSON请求,生成JSON响应) - a trait
RpcTransport
描述了JSON-RPC客户端请求者(给定JSON请求,与其他人通信以生成JSON响应)
- a trait
[nanorpc_derive]
,给定一个描述RPC方法、它们的参数类型和它们的返回类型的FooProtocol
trait,派生- 一个结构体
FooService
,它接受任何实现了FooProtocol
的“业务逻辑”结构体,并将其包装成实现了RpcService
的东西。 - 一个结构体
FooClient
,它接受任何实现了RpcTransport
的 JSON 传输,并将其包装成具有对应 RPC 方法的结构体。
- 一个结构体
例如
#[nanorpc_derive]
#[async_trait]
pub trait MathProtocol {
/// Adds two numbers. Arguments and return type must be JSON-serializable through `serde_json`
async fn add(&self, x: f64, y: f64) -> f64;
/// Multiplies two numbers
async fn mult(&self, x: f64, y: f64) -> f64;
}
// Autogenerates a server struct:
pub struct MathService<T: MathProtocol>(pub T);
#[async_trait]
impl <T: MathService> RpcService for MathService<T> {
//...
}
// Autogenerates a client struct like:
pub struct MathClient<T: RpcTransport>(pub T);
impl <T: RpcTransport> MathClient {
/// Adds two numbers
pub async fn add(&self, x: f64, y: f64) -> Result<f64, T::Error>;
//...
}
在 JSON 层面上,上述协议将响应一个 JSON-RPC 2.0 请求
{"jsonrpc": "2.0", "method": "mult", "params": [42, 23], "id": 1}
以
{"jsonrpc": "2.0", "result": 966, "id": 1}
依赖关系
~1.5MB
~35K SLoC