gRPC para Rust: bibliotecas e exemplos
gRPC é um framework de alto desempenho para chamada remota de procedimentos (RPC), desenvolvido pelo Google. Ele usa Protocol Buffers (protobuf) para serialização de dados e HTTP/2 para transporte. No ecossistema Rust, as principais bibliotecas para trabalhar com gRPC são tonic e grpc-rs. Neste artigo, abordaremos detalhadamente ambas as bibliotecas, seus recursos e forneceremos exemplos práticos de código.
Por que gRPC em Rust?
Rust é uma linguagem de programação de sistemas com foco em segurança de memória e desempenho. O gRPC em Rust permite criar:
- Microsserviços de alta carga
- Serviços de streaming em tempo real
- Aplicações cliente-servidor multiplataforma
- Integração com infraestrutura gRPC existente
Principais bibliotecas
1. Tonic — escolha moderna e recomendada
Tonic é uma biblioteca gRPC assíncrona, construída sobre tokio e hyper. É ativamente mantida pela comunidade e considerada o padrão para gRPC em Rust.
Vantagens do tonic:
- Suporte completo a gRPC (fluxos unários, do servidor, do cliente e bidirecionais)
- Geração de código via
tonic-buildbaseada em arquivos.proto - Integração com
tokio(runtime assíncrono) - Suporte a TLS, balanceamento de carga e interceptadores
- Comunidade ativa e boa documentação
2. grpc-rs — alternativa da PingCAP
grpc-rs é um wrapper Rust sobre a biblioteca C gRPC Core. Usado no projeto TiKV. Adequado para casos que exigem máxima compatibilidade com a pilha C original do gRPC.
Características do grpc-rs:
- Wrapper sobre gRPC Core (biblioteca C)
- Suporte a todos os tipos de chamadas gRPC
- Menos "magia" — mais controle
- Requer instalação de
protocecmake - Menos popular em comparação com tonic
Recomendação: Para a maioria dos novos projetos, escolha tonic. O grpc-rs deve ser usado se você precisar de integração com código C gRPC existente.
Configuração de projeto com tonic
Crie um novo projeto:
cargo new grpc-examplecd grpc-exampleAdicione as dependências no Cargo.toml:
[dependencies]tonic = "0.11"prost = "0.12"tokio = { version = "1", features = ["full"] }
[build-dependencies]tonic-build = "0.11"Crie o arquivo proto/hello.proto:
syntax = "proto3";
package hello;
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply);}
message HelloRequest { string name = 1;}
message HelloReply { string message = 1;}Configure a compilação — crie build.rs:
fn main() -> Result<(), Box<dyn std::error::Error>> { tonic_build::compile_protos("proto/hello.proto")?; Ok(())}Exemplo de servidor com tonic
Crie src/server.rs:
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 {