如何为buf CLI添加RUST插件以生成proto文件的RUST库
用Buf CLI生成Rust版gRPC服务端/客户端库的实现策略
一、安装必要的Rust插件
Buf依赖protoc-gen-rust和protoc-gen-rust-grpc两个插件,分别生成Protobuf消息序列化代码和gRPC服务端/客户端骨架。先通过Cargo安装:
cargo install protoc-gen-rust protoc-gen-rust-grpc
确保本地已配置Rust环境(通过rustup安装),安装完成后插件会自动加入系统PATH,Buf能直接识别。
二、修正buf.gen.yaml配置
你原注释的配置重复了rust插件,Rust需要两个独立插件配合:rust处理Protobuf消息,rust-grpc处理gRPC服务逻辑。更新后的配置如下:
version: v1 plugins: - name: go out: gen/go opt: paths=source_relative - name: go-grpc out: gen/go opt: - paths=source_relative - require_unimplemented_servers=false - name: rust out: gen/rust opt: paths=source_relative - name: rust-grpc out: gen/rust opt: - paths=source_relative - server # 生成服务端代码骨架,仅需客户端可移除该选项
paths=source_relative:保持生成代码的目录结构与proto源文件一致server选项:让rust-grpc生成服务端需要实现的trait和基础结构
三、生成Rust代码
在仓库根目录执行Buf生成命令:
buf generate
生成的代码会输出到gen/rust目录下。
四、在Rust项目中引入生成代码
在你的Rust项目Cargo.toml中添加必要依赖(生成的代码依赖这些库):
[dependencies] prost = "0.12" # Rust Protobuf序列化核心库 tonic = "0.10" # Rust异步gRPC框架 prost-types = "0.12" # 通用Protobuf类型支持 tokio = { version = "1.0", features = ["full"] } # Tonic依赖的异步runtime
五、验证代码可用性
服务端实现示例
假设你的proto定义了Greeter服务,实现生成的GreeterServer trait:
use tonic::{Request, Response, Status}; // 导入路径需根据你的proto结构调整 use crate::gen::rust::helloworld::greeter_server::{Greeter, GreeterServer}; use crate::gen::rust::helloworld::{HelloRequest, HelloResponse}; #[derive(Debug, Default)] pub struct MyGreeterService {} #[tonic::async_trait] impl Greeter for MyGreeterService { async fn say_hello(&self, request: Request<HelloRequest>) -> Result<Response<HelloResponse>, Status> { let req_inner = request.into_inner(); let reply = HelloResponse { message: format!("Hello, {}!", req_inner.name), }; Ok(Response::new(reply)) } } #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let addr = "[::1]:50051".parse()?; let greeter = MyGreeterService::default(); tonic::transport::Server::builder() .add_service(GreeterServer::new(greeter)) .serve(addr) .await?; Ok(()) }
客户端调用示例
use tonic::transport::Channel; use crate::gen::rust::helloworld::greeter_client::GreeterClient; use crate::gen::rust::helloworld::HelloRequest; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut client = GreeterClient::connect("http://[::1]:50051").await?; let request = tonic::Request::new(HelloRequest { name: "Rust gRPC".into(), }); let response = client.say_hello(request).await?; println!("服务端响应: {:?}", response.into_inner()); Ok(()) }
内容的提问来源于stack exchange,提问作者IrishGringo
相关产品推荐
相关产品推荐

