Qu'est-ce que Tonic et pourquoi l'utiliser ?
Tonic est une bibliothèque moderne et haute performance pour implémenter des serveurs et clients gRPC en Rust. Elle repose sur le runtime asynchrone Tokio et le framework HTTP/2 Hyper, garantissant des performances maximales et une compatibilité totale avec le standard gRPC.
Principaux avantages de Tonic :
- Asynchrone natif — entièrement async/await, sans blocage
- Sécurité des types — génération de code à partir de fichiers proto à la compilation
- Support de tous les patterns gRPC — unary, server streaming, client streaming, bidirectional streaming
- Intégration avec l'écosystème Rust — compatible avec Tokio, Tower, Hyper et d'autres crates populaires
- Performances — l'un des frameworks gRPC les plus rapides
Cette bibliothèque est utilisée en production par des entreprises comme Discord, Microsoft, Amazon et bien d'autres. Tonic est idéal pour créer des microservices, des passerelles API et tout système distribué nécessitant une communication efficace entre services.
Installation de Tonic
Pour travailler avec Tonic, vous devez installer plusieurs dépendances. Ajoutez-les à votre fichier Cargo.toml :
[dependencies]
tonic = "0.12"
prost = "0.13"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
[build-dependencies]
tonic-build = "0.12"
Explication des dépendances :
tonic— la bibliothèque principale pour gRPCprost— générateur de code Protocol Buffers pour Rusttokio— le runtime asynchronetonic-build— utilisé à la compilation pour traiter les fichiers .proto
Vous aurez également besoin d'installer protoc, le compilateur Protocol Buffers. Sur Ubuntu/Debian :
sudo apt install protobuf-compiler
Sur macOS :
brew install protobuf
Sur Windows, téléchargez le binaire depuis le dépôt officiel et ajoutez-le à votre PATH.
Premiers pas : Hello World avec gRPC
Créons un service simple qui reçoit un nom et renvoie un message de bienvenue.
Étape 1. Créez le fichier proto/helloworld.proto :
syntax = "proto3";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Étape 2. Créez build.rs à la racine du projet :
fn main() -> Result<(), Box> {
tonic_build::compile_protos("proto/helloworld.proto")?;
Ok(())
}
Étape 3. Implémentez le serveur (src/server.rs) :
use tonic::{transport::Server, Request, Response, Status};
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloRequest, HelloReply};
pub mod hello_world {
tonic::include_proto!("helloworld");
}
#[derive(Default)]
pub struct MyGreeter;
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request,
) -> Result, Status> {
let name = request.into_inner().name;
let reply = HelloReply {
message: format!("Bonjour, {} !", name),
};
Ok(Response::new(reply))
}
}
#[tokio::main]
async fn main() -> Result<(), Box> {
let addr = "[::1]:50051".parse()?;
let greeter = MyGreeter::default();
Server::builder()
.add_service(GreeterServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}
Étape 4. Créez le client