0Pricing
Learn Rust Coding · Aula

Gerando código com tonic-build

Compile proto em Rust.

Gerando código com tonic-build é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 2 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 que tonic-build Faz

tonic-build é executado durante a compilação e transforma seus arquivos .proto em código-fonte Rust. Ele encapsula prost-build para as mensagens e acrescenta os traços de serviço gRPC e os clientes.

Ele é executado a partir de um script de compilação do Cargo (build.rs), portanto a geração ocorre automaticamente antes da compilação do seu crate.

Dependências do Cargo

Você precisa de crates de execução e de um crate usado durante a compilação. tonic e prost são dependências normais; tonic-build fica em [build-dependencies].

tonic depende de tokio como seu ambiente de execução assíncrono, portanto inclua-o também.

[dependencies]
tonic = "0.12"
prost = "0.13"
tokio = { version = "1", features = ["full"] }

[build-dependencies]
tonic-build = "0.12"

Um build.rs Mínimo

Crie build.rs na raiz do crate. Chame tonic_build::compile_protos passando o caminho para o arquivo proto.

Por padrão, isso compila o código do cliente e do servidor e o grava em OUT_DIR do Cargo.

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_build::compile_protos("proto/greeter.proto")?;
    Ok(())
}

Configurando o Construtor

Para ter mais controle, use tonic_build::configure(). Você pode desativar a geração do cliente ou do servidor, definir caminhos de saída ou adicionar atributos de tipo.

Aqui geramos o servidor, mas ignoramos o cliente, o que é útil para um crate exclusivo de back-end.

tonic_build::configure()
    .build_client(false)
    .build_server(true)
    .compile_protos(&["proto/greeter.proto"], &["proto"])?;

Caminhos de Inclusão

O segundo argumento de compile_protos é a lista de diretórios de inclusão. As importações dentro do seu proto, como google/protobuf/empty.proto, são resolvidas em relação a essas raízes.

Sempre inclua o diretório que contém seus arquivos proto, para que as importações entre arquivos sejam resolvidas.

tonic_build::configure()
    .compile_protos(
        &["proto/greeter.proto", "proto/health.proto"],
        &["proto"],
    )?;

Onde o Código Fica

Os arquivos gerados são gravados no diretório indicado pela variável de ambiente OUT_DIR, com nomes baseados no pacote proto, por exemplo greeter.v1.rs.

Você os inclui no crate com a macro include_proto! dentro de um módulo.

pub mod greeter {
    pub mod v1 {
        tonic::include_proto!("greeter.v1");
    }
}

O que é Gerado

Para cada serviço, tonic produz um módulo de servidor com um traço (por exemplo, greeter_server::Greeter) e um invólucro GreeterServer, além de uma estrutura de cliente GreeterClient.

Cada mensagem se torna uma estrutura Rust que deriva Clone, PartialEq e o Message do prost.

// generated (sketch):
// pub mod greeter_server { pub trait Greeter { /* methods */ } }
// pub mod greeter_client { pub struct GreeterClient<T> { /* ... */ } }

Adicionando Derivações com type_attribute

É comum querer derivações adicionais nas estruturas geradas, como serde::Serialize. Use type_attribute para injetar atributos em tipos específicos ou em todos eles com ..

Isso permite que as mensagens geradas sejam usadas em APIs JSON ou em dados de teste.

tonic_build::configure()
    .type_attribute(".", "#[derive(serde::Serialize)]")
    .compile_protos(&["proto/greeter.proto"], &["proto"])?;

Acionando Recompilações

O Cargo executa novamente build.rs apenas quando entende que as entradas foram alteradas. Emita linhas cargo:rerun-if-changed para que as edições nos arquivos proto forcem a regeneração.

Sem isso, um proto alterado talvez não seja regenerado até que você modifique um arquivo Rust.

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("cargo:rerun-if-changed=proto/greeter.proto");
    tonic_build::compile_protos("proto/greeter.proto")?;
    Ok(())
}

Requisito do protoc

Historicamente, tonic-build executava o compilador protoc externamente, e ele precisava estar instalado. As versões modernas podem usar o analisador protox, escrito totalmente em Rust, para evitar essa dependência.

Se você vir um erro indicando que o protoc não foi encontrado, instale o protoc ou ative um recurso de compilador incorporado.

// In CI you may install protoc, e.g.:
// apt-get install -y protobuf-compiler

Conjuntos de Descritores de Arquivos

Para reflexão ou ferramentas avançadas, peça ao tonic-build que emita um conjunto de descritores de arquivos com file_descriptor_set_path.

Os bytes resultantes podem alimentar tonic-reflection, permitindo que ferramentas como grpcurl descubram seus serviços durante a execução.

tonic_build::configure()
    .file_descriptor_set_path(
        std::env::var("OUT_DIR").unwrap() + "/greeter.bin")
    .compile_protos(&["proto/greeter.proto"], &["proto"])?;

Verificação Rápida

Para onde vai o código gerado pelo tonic e como ele é carregado?

Recapitulação

Você configurou as dependências, escreveu um build.rs, configurou a geração do cliente e do servidor e os caminhos de inclusão, carregou o código por meio de include_proto!, adicionou derivações, tratou os gatilhos de recompilação e aprendeu sobre protoc e conjuntos de descritores.

Em seguida, você implementará o traço de servidor gerado pelo tonic.

Perguntas Frequentes

A aula “Gerando código com tonic-build” é grátis?

Sim — o texto completo de “Gerando código com tonic-build” é 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 “Gerando código com tonic-build”?

Compile proto em Rust. 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 2 de 4.

Quanto tempo leva a aula “Gerando código com tonic-build”?

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