Skip to content

Add Rust Getting Started Codelab #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Aug 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0297a53
added stencil code
cjqzhao Jul 10, 2025
96bb413
added completed code
cjqzhao Jul 10, 2025
b680d26
add completed cargo.toml
cjqzhao Jul 10, 2025
e38fb42
use tonic protobuf build
cjqzhao Jul 10, 2025
8b1fe99
correct completed code
cjqzhao Jul 11, 2025
d3fe7b3
fix something minor
cjqzhao Jul 11, 2025
d2b4009
fixed grpc include
cjqzhao Jul 15, 2025
c4094b4
saving
cjqzhao Jul 15, 2025
744f007
remove unnecessary dependencies
cjqzhao Jul 15, 2025
62c52cb
uncommmented code
cjqzhao Jul 15, 2025
6fa8de8
add completed codelab
cjqzhao Jul 24, 2025
0c50f20
add README
cjqzhao Jul 24, 2025
b2e58e4
added stencil
cjqzhao Jul 24, 2025
41a11a8
fix using proto!
cjqzhao Jul 24, 2025
b3b746d
fix up readme a bit
cjqzhao Jul 24, 2025
32d359d
fixed data.rs
cjqzhao Jul 24, 2025
a2ff3e6
implement suggestions
cjqzhao Jul 25, 2025
61bdf67
fixed some changes
cjqzhao Jul 25, 2025
2e2545f
update dependencies
cjqzhao Jul 31, 2025
dbc43f5
updated codegen
cjqzhao Jul 31, 2025
1cad5e4
Merge branch 'main' of https://github.com/grpc-ecosystem/grpc-codelab…
cjqzhao Aug 7, 2025
9fe6963
give users pregenerated code
cjqzhao Aug 7, 2025
e4b8380
fix stencil code to have generated code
cjqzhao Aug 7, 2025
08b5baf
add tutorial for generating code
cjqzhao Aug 12, 2025
6f985dc
saving changes
cjqzhao Aug 12, 2025
58cb309
move routeguide.proto to proto
cjqzhao Aug 12, 2025
b04e972
update build.rs command
cjqzhao Aug 12, 2025
caed74e
update codelab
cjqzhao Aug 12, 2025
6fa337f
comment out imports in client.rs
cjqzhao Aug 12, 2025
53eaac9
remove the cargo build target
cjqzhao Aug 12, 2025
e5323d8
delete bin binaries
cjqzhao Aug 12, 2025
dd34e2a
removed comments
cjqzhao Aug 13, 2025
429cf0b
fix tutorial
cjqzhao Aug 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions codelabs/grpc-rust-getting-started/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Generate Code from Proto Files

This is a tutorial for generating code from Proto files using gRPC-Rust. This tutorial will utilize the RouteGuide example.

### Prerequisites

* [**Tonic**](https://github.com/hyperium/tonic.git), the open source repository that gRPC-Rust is build off on
```sh
$ git clone https://github.com/hyperium/tonic.git
```
* [**Rust**](https://www.rust-lang.org/).
* Follow installation instructions [here](https://www.rust-lang.org/tools/install).
* [**Bazel 8.3.1**](https://bazel.build/).
* Follow installation instructions [here](https://github.com/bazelbuild/bazel/releases).
* [**Protocol buffer**](https://developers.google.com/protocol-buffers) **compiler**, `protoc`, [version 3](https://protobuf.dev/programming-guides/proto3).
* For installation instructions, see [Protocol Buffer Compiler Installation](https://grpc.io/docs/protoc-installation/).
* NOTE: Must need a version of Protoc 3.31.1 or higher.
* **Rust plugins** for the protocol compiler:
```sh
$ cd tonic/protoc-gen-rust-grpc
$ bazel build //src:protoc-gen-rust-grpc
$ PLUGIN_PATH="$(pwd)/bazel-bin/src/protoc-gen-rust-grpc"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We don't need to set PLUGIN_PATH, it's not used later.

```

* Update your PATH so that the protoc compiler can find the plugins:

```sh
export PATH="$(pwd)/bazel-bin/src/:$PATH"
```

## Generating client and server code

Next we need to generate the gRPC client and server interfaces from our `.proto`
service definition.

### Dependencies
Edit `Cargo.toml` and add the dependency we'll need for this example, which is tonic-protobuf-build:

```console
cargo add tonic-protobuf-build
```

### Compiling and Building Proto
Create a `build.rs` file at the root of your crate. A build.rs script is a Rust program that Cargo executes before compiling your main project. Its purpose is to perform tasks like generating source code, linking to non-Rust libraries, or setting environment variables that influence the build process.

In this case, we will be putting the command to compile and build the `.proto` file in build.rs. We will use gRPC's tonic_protobuf_build crate to generate code from the `.proto` file.
```rust
fn main() {
tonic_protobuf_build::CodeGen::new()
.include("proto")
.inputs(["routeguide.proto"])
.output_dir("generated")
.compile()
.unwrap();
}
```
Now, run
```shell
$ cargo build
```

That's it. The generated code contains:

- Struct definitions for message types `Point` and `Feature`.
- A service trait we'll need to implement: `route_guide_server::RouteGuide`.
- A client type we'll use to call the server: `route_guide_client::RouteGuideClient<T>`.

If your are curious as to where the generated files are, keep reading. The mystery will be revealed
soon! We can now move on to the fun part.

## Bringing Generated Code into Scope

The generated code is placed inside our target directory, in a location defined by the `OUT_DIR`
environment variable that is set by cargo. For our example, this means you can find the generated
code in a path similar to `target/debug/build/routeguide/out/routeguide.rs`.

We can use gRPC's `include_proto` macro to bring the generated code into scope:

```rust
pub mod routeguide {
tonic::include_proto!("routeguide");
}
```

**Note**: The token passed to the `include_proto` macro (in our case "routeguide") is the name of
the package declared in our `.proto` file, not a filename, e.g "routeguide.rs".

With this in place, we can stub out our service implementation:

44 changes: 44 additions & 0 deletions codelabs/grpc-rust-getting-started/completed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
edition = "2021"
license = "MIT"
name = "getting-started"

[[bin]]
name = "routeguide-server"
path = "src/server/server.rs"

[[bin]]
name = "routeguide-client"
path = "src/client/client.rs"

[features]
routeguide = ["dep:async-stream", "dep:tokio-stream", "dep:rand", "dep:serde", "dep:serde_json"]
full = ["routeguide"]
default = ["full"]

[dependencies]
# Common dependencies
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
prost = "0.14"
tonic = { git = "https://github.com/hyperium/tonic", branch="master"}
tonic-protobuf = {git = "https://github.com/hyperium/tonic", branch="master", package = "tonic-protobuf" }
grpc = {git = "https://github.com/hyperium/tonic", branch="master", package = "grpc"}
# Optional dependencies
async-stream = { version = "0.3", optional = true }
tokio-stream = { version = "0.1", optional = true }
tokio-util = { version = "0.7.8", optional = true }
tower = { version = "0.5", optional = true }
rand = { version = "0.9", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
prost-types = { version = "0.14", optional = true }
http = { version = "1", optional = true }
hyper = { version = "1", optional = true }
hyper-util = { version = "0.1.4", optional = true }
tokio-rustls = { version = "0.26.1", optional = true, features = ["ring", "tls12"], default-features = false }
hyper-rustls = { version = "0.27.0", features = ["http2", "ring", "tls12"], optional = true, default-features = false }
tower-http = { version = "0.6", optional = true }
protobuf = { version = "4.31.1-release"}

[build-dependencies]
protobuf-codegen = { version = "4.31.1-release"}
8 changes: 8 additions & 0 deletions codelabs/grpc-rust-getting-started/completed/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
protobuf_codegen::CodeGen::new()
.include("proto")
.inputs(["routeguide.proto"])
.output_dir("generated")
.compile_only()
.unwrap();
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[path = "routeguide.u.pb.rs"]
#[allow(nonstandard_style)]
pub mod internal_do_not_use_routeguide;
#[allow(unused_imports, nonstandard_style)]
pub use internal_do_not_use_routeguide::*;
Loading