Compiling Protos with tonic-prost-build
.proto files are not read at runtime: they are compiled at build time and generate the Rust code for the service, the message types, and optionally a descriptor for reflection.
build.rs
Any project using gRPC controllers needs a build.rs file that compiles the .proto files with tonic_prost_build. In Sword, it also generates sword_descriptor_set.bin in OUT_DIR to enable reflection.
// build.rs
use std::{env, path::PathBuf};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
let descriptor_path = out_dir.join("sword_descriptor_set.bin");
tonic_prost_build::configure()
.file_descriptor_set_path(&descriptor_path)
.compile_protos(&["config/proto/users.proto"], &["config/proto"])?;
Ok(())
}Breakdown of the configuration:
.file_descriptor_set_path(...): writes the descriptor toOUT_DIR/sword_descriptor_set.bin. This is what lets Sword register reflection automatically..compile_protos(&["config/proto/users.proto"], &["config/proto"]): compiles the contract and its imports, usingconfig/protoas the resolution root.
Sword registers the descriptor automatically
You do not need to register reflection manually in your modules. Just by generating sword_descriptor_set.bin in OUT_DIR, Sword detects it and exposes it.
Without OUT_DIR there is no reflection
If you omit .file_descriptor_set_path(...), the code still compiles, but there will be no descriptor available, and grpcurl will not be able to list/describe services with reflection.
Dependencies
In your Cargo.toml you need tonic-prost-build as a build dependency, plus prost and tonic-prost at runtime:
[dependencies]
sword = { version = "x.y.z", features = ["grpc", "grpc-reflection"] }
tonic = "x.y.z"
prost = "x.y.z"
tonic-prost = "x.y.z"
[build-dependencies]
tonic-prost-build = "x.y.z"Why prost and tonic-prost at runtime too?
The code generated by the compilation depends on prost (serialization) and tonic-prost (codec) in the final project. sword cannot re-export them in your place.

