概要
RustでgRPCのHello World!をするまでの手順のメモです。
コードの意味などは理解できていないですが、まずは動かしてみることを目的にしています。
下記のページを参考にしています。
https://github.com/hyperium/tonic/blob/master/examples/helloworld-tutorial.md
プロジェクト作成
% cargo new grpc_hello_world
% cd grpc_hello_world
protoファイルの配置
proto/helloworld.proto
を次のように作成する。
syntax = "proto3";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Cargo.tomlに設定追加
[package]
name = "grpc_hello_world"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "helloworld-server"
path = "src/server.rs"
[dependencies]
tonic = "0.7"
prost = "0.10"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
[build-dependencies]
tonic-build = "0.7"
protoからコード生成するためのプログラムの追加
プロジェクト直下に build.rs
というファイルを下記のように作成。
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/helloworld.proto")?;
Ok(())
}
サーバのプログラムを追加
参考ページに従い、 src/server.rs
を下記のように作成。
use tonic::{transport::Server, Request, Response, Status};
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloReply, HelloRequest};
pub mod hello_world {
tonic::include_proto!("helloworld");
}
#[derive(Debug, Default)]
pub struct MyGreeter {}
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<HelloRequest>,
) -> Result<Response<HelloReply>, Status> {
println!("Got a request: {:?}", request);
let reply = hello_world::HelloReply {
message: format!("Hello {}!", request.into_inner().name).into(),
};
Ok(Response::new(reply))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let greeter = MyGreeter::default();
Server::builder()
.add_service(GreeterServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}
gRPCサーバの起動
依存packageのコンパイルの後、サーバが起動する。
% cargo run --bin helloworld-server
...
Finished dev [unoptimized + debuginfo] target(s) in 0.09s
Running `target/debug/helloworld-server`
grpcurlでRPCを叩いてみる
% grpcurl -plaintext -import-path ./proto -proto helloworld.proto -d '{"name": "World"}' '[::]:50051' helloworld.Greeter/SayHello
{
"message": "Hello World!"
}