Implementando um servidor gRPC
Ofereça métodos RPC unários.
Implementando um servidor gRPC é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.
O Traço de Servidor Gerado
Para um serviço chamado Greeter, tonic gera um traço em greeter_server. Você o implementa na sua própria estrutura para fornecer o comportamento.
O traço é async por meio de #[tonic::async_trait], portanto cada método é uma fn assíncrona que retorna um Result.
use greeter::v1::greeter_server::{Greeter, GreeterServer};
use greeter::v1::{HelloRequest, HelloReply};Invólucros de Requisição e Resposta
Os métodos recebem um tonic::Request<T> e retornam um tonic::Response<T>. Esses invólucros carregam metadados, extensões e a mensagem interna.
Chame .into_inner() para obter a mensagem decodificada e Response::new(..) para criar uma resposta.
let req: HelloRequest = request.into_inner();
let reply = HelloReply { message: format!("Hi {}", req.name) };
Ok(Response::new(reply))Uma Estrutura de Servidor
Defina uma estrutura para armazenar qualquer estado compartilhado, como um conjunto de conexões com o banco de dados. Quando não há estado, é comum derivar Default.
Você implementará o traço gerado nessa estrutura.
#[derive(Default)]
pub struct MyGreeter {}Implementando um Método Unário
Anote o bloco impl com #[tonic::async_trait] e implemente cada rpc como uma fn assíncrona que corresponda à assinatura gerada.
Retorne Ok(Response::new(reply)) em caso de sucesso.
#[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;
Ok(Response::new(HelloReply { message: format!("Hello {name}") }))
}
}Retornando Erros com Status
Os erros são retornados como tonic::Status, que é mapeado para um código de status gRPC. Use construtores como Status::invalid_argument ou Status::not_found.
A mensagem é enviada ao cliente junto com o código.
if name.is_empty() {
return Err(Status::invalid_argument("name must not be empty"));
}Construindo e Servindo
Use tonic::transport::Server em um main assíncrono. Adicione seu serviço envolvido no tipo ...Server gerado e, em seguida, chame serve com um endereço de soquete.
A macro #[tokio::main] fornece o ambiente de execução.
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve(addr)
.await?;
Ok(())
}Respostas com Fluxo do Servidor
Um método com fluxo do servidor retorna um tipo de fluxo. tonic usa um tipo associado junto com um fluxo em caixa; um canal mpsc é uma forma comum de fornecer mensagens.
Você retorna um ReceiverStream envolvido em uma Response.
use tokio_stream::wrappers::ReceiverStream;
let (tx, rx) = tokio::sync::mpsc::channel(8);
tokio::spawn(async move { tx.send(Ok(reply)).await.ok(); });
Ok(Response::new(ReceiverStream::new(rx)))Lendo Metadados
Os metadados da solicitação contêm cabeçalhos, como tokens de autenticação. Acesse-os com request.metadata() antes de consumir o corpo.
As chaves são ASCII e não diferenciam maiúsculas de minúsculas; os valores são retornados como MetadataValue.
if let Some(token) = request.metadata().get("authorization") {
// validate token
} else {
return Err(Status::unauthenticated("missing token"));
}Interceptadores
Um interceptador é executado antes de cada solicitação, sendo ideal para autenticação ou registro. Ele recebe a Request e a retorna ou devolve um erro Status.
Anexe-o com with_interceptor ao adicionar o serviço.
fn auth(req: Request<()>) -> Result<Request<()>, Status> {
match req.metadata().get("authorization") {
Some(_) => Ok(req),
None => Err(Status::unauthenticated("no token")),
}
}
// .add_service(GreeterServer::with_interceptor(svc, auth))Encerramento Elegante
Use serve_with_shutdown para parar de aceitar conexões quando um futuro for resolvido, como no caso de um sinal Ctrl-C.
As solicitações em andamento são concluídas antes da saída do servidor, evitando encerramentos abruptos.
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve_with_shutdown(addr, async {
tokio::signal::ctrl_c().await.ok();
})
.await?;Estado Compartilhado
Para compartilhar estado mutável entre solicitações, armazene-o atrás de Arc e de um primitivo de sincronização, como tokio::sync::Mutex, dentro da estrutura do servidor.
tonic clona o serviço para cada conexão, portanto identificadores compartilhados baratos de clonar são o padrão adequado.
use std::sync::Arc;
use tokio::sync::Mutex;
#[derive(Default)]
pub struct MyGreeter {
hits: Arc<Mutex<u64>>,
}Verificação Rápida
Como os métodos gRPC relatam falhas em tonic?
Recapitulação
Você implementou o traço de servidor gerado: desembrulhou solicitações, retornou respostas e erros Status, serviu com tokio, transmitiu respostas, leu metadados, adicionou interceptadores, realizou um encerramento elegante e compartilhou estado por meio de Arc.
A seguir, você criará um cliente para chamar este servidor.
Perguntas Frequentes
A aula “Implementando um servidor gRPC” é grátis?
Sim — o texto completo de “Implementando um servidor gRPC” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.
O que vou aprender em “Implementando um servidor gRPC”?
Ofereça métodos RPC unários. Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Learn Rust Coding?
Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Implementando um servidor gRPC”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Learn Rust Coding?
Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Definições de Protobuf e serviços
- Gerando código com tonic-build
- Implementando um servidor gRPC
- Chamando a partir de um cliente gRPC