2 个版本
0.3.0 | 2024年7月5日 |
---|
#45 in #proto
409 次每月下载
在 sp1-server 中使用
10KB
93 行
twirp-rs
Twirp 是一种基于 HTTP 和 Protocol Buffers (proto) 的 RPC 协议。 该协议使用 HTTP URL 指定 RPC 端点,并将 proto 消息作为 HTTP 请求/响应体发送/接收。服务在 .proto 文件 中定义,允许轻松实现不同语言中的自动生成客户端和服务器。
规范实现是 Go 语言版本,这是该协议的 Rust 语言实现。Rust 协议缓冲支持由 prost
生态系统提供。
与 prost-twirp
不同,生成用于服务和访问 RPC 的特质是在 async
函数之上实现的。由于在 Rust 1.75 之前的版本中,不支持直接使用包含 async
函数的特质 ,因此此存储库使用 async_trait
宏来封装使其工作所需的框架。
使用方法
查看 示例 以获取完整示例项目。
在 .proto
文件中定义服务和消息
// service.proto
package service.haberdash.v1;
service HaberdasherAPI {
rpc MakeHat(MakeHatRequest) returns (MakeHatResponse);
}
message MakeHatRequest { }
message MakeHatResponse { }
将 twirp-build
存储库添加为您的 Cargo.toml
中的构建依赖项(您还需要 prost-build
)
# Cargo.toml
[build-dependencies]
twirp-build = "0.3"
prost-build = "0.12"
向您的项目添加 build.rs
文件以编译 proto 并生成 Rust 代码
fn main() {
let proto_source_files = ["./service.proto"];
// Tell Cargo to rerun this build script if any of the proto files change
for entry in &proto_source_files {
println!("cargo:rerun-if-changed={}", entry);
}
prost_build::Config::new()
.service_generator(twirp_build::service_generator())
.compile_protos(&proto_source_files, &["./"])
.expect("error compiling protos");
}
这将在 target/build/your-project-*/out/example.service.rs
中生成代码。为了使用此代码,您需要实现定义的服务对应的特质,并将服务处理程序连接到 hyper 网络服务器。有关详细信息,请参阅 示例 main.rs
。
包含生成的代码,创建一个路由器,注册您的服务,然后在 hyper 服务器中提供服务这些路由
mod haberdash {
include!(concat!(env!("OUT_DIR"), "/service.haberdash.v1.rs"));
}
use axum::Router;
use haberdash::{MakeHatRequest, MakeHatResponse};
#[tokio::main]
pub async fn main() {
let api_impl = Arc::new(HaberdasherApiServer {});
let twirp_routes = Router::new()
.nest(haberdash::SERVICE_FQN, haberdash::router(api_impl));
let app = Router::new()
.nest("/twirp", twirp_routes)
.fallback(twirp::server::not_found_handler);
let tcp_listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
if let Err(e) = axum::serve(tcp_listener, app).await {
eprintln!("server error: {}", e);
}
}
// Define the server and implement the trait.
struct HaberdasherApiServer;
#[async_trait]
impl haberdash::HaberdasherApi for HaberdasherApiServer {
async fn make_hat(&self, ctx: twirp::Context, req: MakeHatRequest) -> Result<MakeHatResponse, TwirpErrorResponse> {
todo!()
}
}
该代码创建了一个axum::Router
,然后将它传递给axum::serve()
来处理网络。使用axum::serve
是可选的。构建app
之后,你也可以通过导入twirp::tower::Service
并执行app.call(request).await
来从任何基于hyper
的服务器调用它。
用法(客户端)
在客户端,你还会得到一个生成的twirp客户端(基于你的proto中的rpc端点)。包含生成的代码,创建一个客户端,并开始执行rpc调用
mod haberdash {
include!(concat!(env!("OUT_DIR"), "/service.haberdash.v1.rs"));
}
use haberdash::{HaberdasherApiClient, MakeHatRequest, MakeHatResponse};
#[tokio::main]
pub async fn main() {
let client = Client::from_base_url(Url::parse("https://127.0.0.1:3000/twirp/")?)?;
let resp = client.make_hat(MakeHatRequest { inches: 1 }).await;
eprintln!("{:?}", resp);
}
依赖项
~7–17MB
~231K SLoC