Use the tonic crate, a gRPC over HTTP/2 implementation for Rust, to define services via Protocol Buffers and generate async client/server code. Add tonic and prost to your dependencies, compile your .proto files, and implement the generated trait to handle requests.
[dependencies]
tonic = "0.12"
prost = "0.13"
prost-build = "0.13"
tokio = { version = "1", features = ["full"] }
// src/main.rs
use tonic::transport::Server;
use tonic::Request;
use tonic::Response;
// Generated code from your .proto file
mod hello {
tonic::include_proto!("hello");
}
#[derive(Default)]
struct MyGreeter;
#[tonic::async_trait]
impl hello::greeter_server::Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<hello::HelloRequest>,
) -> Result<Response<hello::HelloReply>, tonic::Status> {
let name = request.into_inner().name;
Ok(Response::new(hello::HelloReply {
message: format!("Hello {}!", name),
}))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::]:50051".parse()?;
let greeter = MyGreeter::default();
Server::builder()
.add_service(hello::greeter_server::GreeterServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}