0Pricing
Learn Rust Coding · Lezione

Generare codice con tonic-build

Compili proto in Rust.

Generare codice con tonic-build è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 4 lezioni in totale.

Cosa fa tonic-build

tonic-build viene eseguito in fase di compilazione e trasforma i file .proto in codice sorgente Rust. Incapsula prost-build per i messaggi e aggiunge i trait dei servizi gRPC e i client.

Viene eseguito da uno script di build di Cargo (build.rs), quindi la generazione avviene automaticamente prima della compilazione del crate.

Dipendenze di Cargo

Sono necessari crate runtime e un crate per la fase di build. tonic e prost sono dipendenze normali; tonic-build va inserito in [build-dependencies].

tonic usa tokio come runtime asincrono, quindi lo includa a sua volta.

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

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

Un build.rs minimale

Crei build.rs nella radice del crate. Chiami tonic_build::compile_protos indicando il percorso del file proto.

Per impostazione predefinita, questo compila sia il codice client sia quello server e lo scrive nella OUT_DIR di Cargo.

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

Configurare il builder

Per un controllo maggiore, usi tonic_build::configure(). È possibile disabilitare la generazione del client o del server, impostare i percorsi di output oppure aggiungere attributi ai tipi.

Qui generiamo il server ma ignoriamo il client, una scelta utile per un crate esclusivamente backend.

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

Percorsi di inclusione

Il secondo argomento di compile_protos è l'elenco delle directory di inclusione. Gli import all'interno del proto, come google/protobuf/empty.proto, vengono risolti rispetto a queste radici.

Includa sempre la directory che contiene i file proto, così gli import tra file possono essere risolti.

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

Dove finisce il codice

I file generati vengono scritti nella directory indicata dalla variabile d'ambiente OUT_DIR, con un nome basato sul package proto, ad esempio greeter.v1.rs.

Li si include nel crate con la macro include_proto! all'interno di un modulo.

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

Cosa viene generato

Per ogni servizio tonic produce un modulo server con un trait (ad esempio greeter_server::Greeter) e un wrapper GreeterServer, oltre a una struct client GreeterClient.

Ogni messaggio diventa una struct Rust che deriva Clone, PartialEq e Message di prost.

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

Aggiungere derive con type_attribute

Spesso si desiderano derive aggiuntivi sulle struct generate, come serde::Serialize. Usi type_attribute per inserire attributi su tipi specifici o su tutti i tipi con ..

In questo modo i messaggi generati possono essere usati nelle API JSON o nei fixture dei test.

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

Attivare le ricompilazioni

Cargo esegue nuovamente build.rs solo quando ritiene che gli input siano cambiati. Emetta righe cargo:rerun-if-changed affinché le modifiche ai file proto forzino la rigenerazione.

Senza questa configurazione, un proto modificato potrebbe non essere rigenerato finché non viene modificato un file 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 di protoc

Storicamente, tonic-build eseguiva il compilatore protoc, che doveva essere installato. Le versioni moderne possono usare il parser protox interamente scritto in Rust per evitare questa dipendenza.

Se compare un errore relativo a protoc mancante, installi protoc oppure abiliti una funzionalità per un compilatore incluso nel progetto.

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

Insiemi di descrittori dei file

Per la reflection o per strumenti avanzati, chieda a tonic-build di generare un insieme di descrittori dei file con file_descriptor_set_path.

I byte risultanti possono essere forniti a tonic-reflection, consentendo a strumenti come grpcurl di individuare i servizi durante l'esecuzione.

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

Verifica rapida

Dove viene inserito il codice tonic generato e come viene caricato?

Riepilogo

Ha configurato le dipendenze, scritto un build.rs, configurato la generazione di client e server e i percorsi di inclusione, caricato il codice tramite include_proto!, aggiunto i derive, gestito i trigger di ricompilazione e appreso informazioni su protoc e sugli insiemi di descrittori.

Ora implementerà il trait del server generato da tonic.

Domande Frequenti

La lezione «Generare codice con tonic-build» è gratuita?

Sì — il testo completo di «Generare codice con tonic-build» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 4 lezioni in totale.

Cosa imparerò in «Generare codice con tonic-build»?

Compili proto in Rust. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Learn Rust Coding?

Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Generare codice con tonic-build»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?

Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Protobuf e definizioni dei servizi
  2. Generare codice con tonic-build
  3. Implementare un server gRPC
  4. Effettuare chiamate da un client gRPC
← Torna a Learn Rust Coding