4个版本 (破坏性更新)
0.4.0 | 2022年7月23日 |
---|---|
0.3.0 | 2022年3月5日 |
0.2.0 | 2022年1月22日 |
0.1.0 | 2021年9月10日 |
0.0.0 |
|
#1978 in 异步
每月下载量 93次
38KB
681 行
涡轮增压
自动生成的异步RPC绑定,通过WebSocket连接将JS或Rust/WASM前端即时连接到Rust后端。
查看https://github.com/trevyn/turbocharger-template-dioxus或https://github.com/trevyn/turbocharger-template-svelte以获取完整的模板仓库。
使Rust 后端 函数,例如
use turbocharger::prelude::*;
#[backend]
pub async fn get_person(id: i64) -> Person {
// ... write any async backend code here; ...
// ... query a remote database, API, etc. ...
Person { name: "Bob", age: 21 }
}
无需额外模板即可即时提供给前端,作为一个
- 异步Rust/WASM函数
- 并且可选地,一个异步JavaScript函数,带有完整的TypeScript类型定义
- 通过网络调用后端
Rust/WASM
let person = get_person(1).await;
JS
// export function get_person(id: number): Promise<Person>;
let person = await backend.get_person(1);
Rust前端可以处理所有可以用 bincode
序列化的类型。
JS前端可以处理所有由 wasm-bindgen
支持的类型,包括大多数基本类型和具有支持类型字段的自定义 struct
,但是尚未支持(这些值将以TypeScript区分联合的形式出现在另一端)enum
变体。
工作原理
过程宏自动生成一个前端 wasm-bindgen
模块,该模块使用 bincode
序列化前端函数调用的参数。这些请求通过共享的WebSocket连接发送到后端服务器上提供的 axum
端点,该端点调用您的后端函数并序列化响应。这是通过WebSocket发送回来的,并解析由原始前端函数调用返回的Promise或Future。
可以在单个多路复用连接上同时进行多个异步请求;一切正常工作。
完整示例:一个完整的SQLite后端和前端绑定的示例
查看https://github.com/trevyn/turbocharger-template-dioxus或https://github.com/trevyn/turbocharger-template-svelte以获取完整的模板仓库。
app.rs
use turbocharger::prelude::*;
use turbosql::Turbosql;
#[backend]
#[derive(Turbosql, Default)]
pub struct Person {
pub rowid: Option<i64>,
pub name: Option<String>,
}
#[backend(js)]
pub async fn insert_person(p: Person) -> Result<i64, tracked::StringError> {
Ok(p.insert()?) // returns rowid
}
#[backend(js)]
pub async fn get_person(rowid: i64) -> Result<Person, tracked::StringError> {
Ok(turbosql::select!(Person "WHERE rowid = ?", rowid)?)
}
server.rs
mod app;
#[tokio::main]
async fn main() {
#[derive(rust_embed::RustEmbed)]
#[folder = "build"]
struct Frontend;
eprintln!("Serving on http://127.0.0.1:8080");
let addr = std::net::SocketAddr::from(([0, 0, 0, 0], 8080));
turbocharger::serve::<Frontend>(&addr).await;
}
wasm.rs
mod app;
index.js
import turbocharger_init, * as backend from "./turbocharger_generated";
(async () => {
await turbocharger_init();
let person = Object.assign(new backend.Person(), { name: "Bob" });
let rowid = await backend.insert_person(person);
console.log((await backend.get_person(rowid)).toJSON());
})();
用法
使用 https://github.com/trevyn/turbocharger-template-dioxus 或 https://github.com/trevyn/turbocharger-template-svelte 启动新项目,以获取完整的项目布局和构建脚本。
您的 app.rs
模块包含在 server.rs
中的服务器 bin
目标以及在 wasm.rs
中的 WASM 目标中。宏 #[backend]
输出三个函数
- 服务器
bin
目标的函数,保持不变;如果您愿意,可以直接从其他服务器代码中调用它。 - 为服务器
bin
目标提供 RPC 分发粘合剂的内部函数。 - 为 WASM 目标提供的一个函数,它执行 RPC 调用并返回响应。
请注意,app.rs
被编译为 wasm32-unknown-unknown
和宿主三元组,并且您可以在 app.rs
中使用 #[backend]
或 #[frontend]
注释函数和结构体。
错误处理
#[backend(js)]
函数需要返回错误时,可以返回一个 Result<T, E: Display>
,其中 T
是与 wasm-bindgen
兼容的类型,而 E
是实现了 Display
的类型,包括实现了 std::error::Error
的任何类型,包括 Box<dyn std::error::Error>>
和 anyhow::Error
。网络边界之外的错误在服务器端通过它们的 to_string()
方法转换为 String
表示,并通过 JS 侧的 Promise 拒绝交付。
返回 Result<T, tracked::StringError>
被推荐,并将产生一个包含错误位置行号的错误。
许可证:MIT 或 Apache-2.0 或 CC0-1.0(公共领域)
依赖关系
~3–22MB
~323K SLoC