How to use tonic crate in Rust gRPC

Use the tonic crate by defining a .proto file, running tonic-build to generate Rust code, and implementing the generated server trait with tokio.

Use tonic by defining your service in a .proto file, generating Rust code with tonic-build, and implementing the server or client using the generated types.

// 1. Add dependencies to Cargo.toml
// tonic = "0.12"
// tonic-build = "0.12"
// tokio = { version = "1", features = ["full"] }

// 2. Build script (build.rs) to compile .proto files
fn main() {
    tonic_build::compile_protos("src/hello.proto").unwrap();
}

// 3. Implement the server in src/main.rs
use tonic::transport::Server;
use tonic::Request;
use my_proto::hello_server::HelloServer;

#[derive(Default)]
struct MyHelloService;

#[tonic::async_trait]
impl hello_server::Hello for MyHelloService {
    async fn say_hello(
        &self,
        request: Request<hello::HelloRequest>,
    ) -> Result<tonic::Response<hello::HelloReply>, tonic::Status> {
        let name = request.into_inner().name;
        Ok(tonic::Response::new(hello::HelloReply {
            message: format!("Hello {}!", name),
        }))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr = "[::1]:50050".parse()?;
    let service = MyHelloService::default();
    Server::builder()
        .add_service(HelloServer::new(service))
        .serve(addr)
        .await?;
    Ok(())
}

// 4. Client usage example // let mut client = hello_client::HelloClient::connect("http://[::1]:50050").await?; // client.say_hello(Request::new(hello::HelloRequest { name: "World".into() })).await?;