gRPC pour Rust : bibliothèques et exemples
\n\ngRPC est un framework d'appel de procédure distante (RPC) haute performance développé par Google. Il utilise Protocol Buffers (protobuf) pour la sérialisation des données et HTTP/2 pour le transport. Grâce à un typage strict, un streaming bidirectionnel et une faible latence, gRPC est devenu un standard pour l'architecture de microservices. Dans l'écosystème Rust, deux bibliothèques principales permettent de travailler avec gRPC : Tonic et grpc-rs. Dans cet article, nous examinerons leurs caractéristiques et fournirons des exemples pratiques.
\n\n1. Tonic — moderne et asynchrone
\nTonic est la bibliothèque gRPC la plus populaire pour Rust. Elle est construite sur tokio et hyper, entièrement asynchrone et s'intègre parfaitement à l'écosystème Rust. Tonic prend en charge les quatre types d'appels gRPC : unaires, streaming serveur, streaming client et streaming bidirectionnel.
Installation et configuration
\nAjoutez les dépendances dans Cargo.toml :
[dependencies]\ntonic = "0.12"\nprost = "0.13"\ntokio = { version = "1", features = ["full"] }\n\n[build-dependencies]\ntonic-build = "0.12"\n\nDéfinition du service protobuf
\nCréez le fichier proto/hello.proto :
syntax = "proto3";\n\npackage hello;\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\nCompilation de protobuf
\nDans build.rs, indiquez :
fn main() -> Result<(), Box<dyn std::error::Error>> {\n tonic_build::compile_protos("proto/hello.proto")?;\n Ok(())\n}\n\nImplémentation du serveur
\nExemple d'un serveur gRPC simple avec Tonic :
\nuse tonic::{transport::Server, Request, Response, Status};\nuse hello::greeter_server::{Greeter, GreeterServer};\nuse hello::{HelloRequest, HelloReply};\n\npub mod hello {\n tonic::include_proto!("hello");\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<HelloRequest>,\n ) -> Result<Response<HelloReply>, Status> {\n let name = request.into_inner().name;\n let reply = HelloReply {\n message: format!("Bonjour, {} !", name),\n };\n Ok(Response::new(reply))\n }\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n let addr = "[::1]:50051".parse()?;\n let greeter = MyGreeter::default();\n\n Server::builder()\n .add_service(GreeterServer::new(greeter))\n .serve(addr)\n .await?;\n\n Ok(())\n}\n\nClient
\nuse hello::greeter_client::GreeterClient;\nuse hello::HelloRequest;\n\npub mod hello {\n tonic::include_proto!("hello");\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n let mut client = GreeterClient::connect("http://[::1]:50051").await?;\n\n let request = tonic::Request::new(HelloRequest {\n name: "Monde".into(),\n });\n\n let response = client.say_hello(request).await?;\n println!("Réponse du serveur : {}", response.into_inner().message);\n Ok(())\n}\n\n2. grpc-rs — une alternative mature
\ngrpc-rs est une bibliothèque de l'équipe TiKV, construite sur la bibliothèque C gRPC Core. Elle offre une compatibilité maximale avec le framework C officiel de gRPC, mais nécessite l'installation de dépendances système (cmake, protobuf). grpc-rs prend en charge les appels synchrones et asynchrones, mais est moins pratique à utiliser que Tonic.
\n\nExemple de serveur avec grpc-rs
\nuse grp