Tonic for Rust: Complete Guide 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

What is Tonic and why is it needed?

\n\n

Tonic is a modern, high-performance library for implementing gRPC servers and clients in Rust. It is built on the Tokio async runtime and the Hyper HTTP/2 framework, providing maximum performance and full compatibility with the gRPC standard.

\n\n

Key advantages of Tonic:

\n
    \n
  • Native asynchronicity — fully async/await, no blocking
  • \n
  • Type safety — code generation from proto files at compile time
  • \n
  • Support for all gRPC patterns — unary, server streaming, client streaming, bidirectional streaming
  • \n
  • Integration with the Rust ecosystem — works with Tokio, Tower, Hyper, and other popular crates
  • \n
  • Performance — one of the fastest gRPC frameworks
  • \n
\n\n

The library is used in production by companies such as Discord, Microsoft, Amazon, and many others. Tonic is ideal for building microservices, API gateways, and any distributed systems that require efficient communication between services.

\n\n

Installing Tonic

\n\n

To work with Tonic, you need to install several dependencies. Add them to your Cargo.toml:

\n\n
[dependencies]\ntonic = "0.12"\nprost = "0.13"\ntokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }\n\n[build-dependencies]\ntonic-build = "0.12"
\n\n

Explanation of dependencies:

\n
    \n
  • tonic — the main library for working with gRPC
  • \n
  • prost — Protocol Buffers code generator for Rust
  • \n
  • tokio — async runtime
  • \n
  • tonic-build — used at build time to compile .proto files
  • \n
\n\n

You will also need to install protoc — the Protocol Buffers compiler. On Ubuntu/Debian:

\n\n
sudo apt install protobuf-compiler
\n\n

On macOS:

\n\n
brew install protobuf
\n\n

On Windows, download the binary from the official repository and add it to your PATH.

\n\n

Quick Start: Hello World on gRPC

\n\n

Let's create a simple service that accepts a name and returns a greeting.

\n\n

Step 1. Create the file proto/helloworld.proto:

\n\n
syntax = "proto3";\n\npackage helloworld;\n\nservice Greeter {\n    rpc SayHello (HelloRequest) returns (HelloReply);\n}\n\nmessage HelloRequest {\n    string name = 1;\n}\n\nmessage HelloReply {\n    string message = 1;\n}
\n\n

Step 2. Create build.rs in the project root:

\n\n
fn main() -> Result<(), Box> {\n    tonic_build::compile_protos("proto/helloworld.proto")?;\n    Ok(())\n}
\n\n

Step 3. Implement the server (src/server.rs):

\n\n
use tonic::{transport::Server, Request, Response, Status};\nuse hello_world::greeter_server::{Greeter, GreeterServer};\nuse hello_world::{HelloRequest, HelloReply};\n\npub mod hello_world {\n    tonic::include_proto!("helloworld");\n}\n\n#[derive(Default)]\npub struct MyGreeter;\n\n#[tonic::async_trait]\nimpl Greeter for MyGreeter {\n    async fn say_hello(\n        &self,\n        request: Request,\n    ) -> Result, Status> {\n        let name = request.into_inner().name;\n        let reply = HelloReply {\n            message: format!("Hello, {}!", name),\n        };\n        Ok(Response::new(reply))\n    }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box> {\n    let addr = "[::1]:50051".parse()?;\n    let greeter = MyGreeter::default();\n\n    Server::builder()\n        .add_service(GreeterServer::new                    

Recommendations