0Pricing
Learn Rust Coding · Aula

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

  1. Definições de Protobuf e serviços
  2. Gerando código com tonic-build
  3. Implementando um servidor gRPC
  4. Chamando a partir de um cliente gRPC
← Voltar para Learn Rust Coding