gRPC in Rust: Tonic and Grpc-rs Libraries with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

gRPC for Rust: Libraries and Examples



gRPC is a high-performance remote procedure call (RPC) framework developed by Google. It uses Protocol Buffers (protobuf) for data serialization and HTTP/2 for transport. Thanks to strict typing, bidirectional streaming, and low latency, gRPC has become a standard for microservice architecture. In the Rust ecosystem, there are two main libraries for working with gRPC: Tonic and grpc-rs. In this article, we will examine their features and provide practical examples.



1. Tonic — Modern and Asynchronous

Tonic is the most popular gRPC library for Rust. It is built on top of tokio and hyper, is fully asynchronous, and integrates well with the Rust ecosystem. Tonic supports all four types of gRPC calls: unary, server streaming, client streaming, and bidirectional streaming.



Installation and Setup

Add dependencies to Cargo.toml:

[dependencies]tonic = "0.12"prost = "0.13"tokio = { version = "1", features = ["full"] }

[build-dependencies]tonic-build = "0.12"


Defining a Protobuf Service

Create a file proto/hello.proto:

syntax = "proto3";

package hello;

service Greeter { rpc SayHello (HelloRequest) returns (HelloReply);}

message HelloRequest { string name = 1;}

message HelloReply { string message = 1;}


Building Protobuf

In build.rs, specify:

fn main() -> Result<(), Box<dyn std::error::Error>> {    tonic_build::compile_protos("proto/hello.proto")?;    Ok(())}


Server Implementation

Example of a simple gRPC server using Tonic:

use tonic::{transport::Server, Request, Response, Status};use hello::greeter_server::{Greeter, GreeterServer};use hello::{HelloRequest, HelloReply};

pub mod hello { tonic::include_proto!("hello");}

#[derive(Default)]pub struct MyGreeter;

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

#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let addr = "[::1]:50051".parse()?; let greeter = MyGreeter::default();

Server::builder() .add_service(GreeterServer::new(greeter)) .serve(addr) .await?;

Ok(())}


Client

use hello::greeter_client::GreeterClient;use hello::HelloRequest;

pub mod hello { tonic::include_proto!("hello");}

#[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: "World".into(), });

let response = client.say_hello(request).await?; println!("Server response: {}", response.into_inner().message); Ok(())}


2. grpc-rs — A Mature Alternative

grpc-rs is a library from the TiKV team, built on top of the C library gRPC Core. It provides maximum compatibility with the official gRPC C framework but requires installing system dependencies (cmake, protobuf). grpc-rs supports synchronous and asynchronous calls but is less convenient to use than Tonic.



Example Server with grpc-rs

use grp                    

Recommendations