Rust🦀で簡易gRPCサーバーを作成して、BloomRPCで動作確認してみたの巻
gRPCについて完全に理解したので、せっかくなのでRustで簡易gRPCサーバーを作成してみたよ!
あと、動作確認にはBloomRPCアプリを使ったから簡単だったよ😊
Rust🦀で簡易gRPCサーバー作成!
完成したリポジトリ:https://github.com/ask-nugey/rust-grpc
いきなりだけど、最終的なディレクリ構成は以下のようになるよ✨↓
rust-grpc/
├── proto/
│ └── greeter.proto
├── src/
│ └── main.rs
├── target/
├── Cargo.lock
├── Cargo.toml
└── build.rs
今回は「名前(文字列)を送ったら挨拶(文字列)を返す」めちゃ簡単なgRPCサーバーを作るよ!
作ったら動作確認もするよ!
実際にプログラミング✨
まずはプロジェクトを作ろー💪
cargo new rust-grpc
protoファイルを作成する!
greeter.protoを作るよ!
rust-grpc/
└── proto/
└── greeter.proto
greeter.protoファイル↓
syntax = "proto3";
package greeter;
message HelloRequest {
string name = 1;
}
message GoodbyeRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
message GoodbyeReply {
string message = 1;
}
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayGoodbye (GoodbyeRequest) returns (GoodbyeReply) {}
}
protoについてはこっち↓を見てね!
Rustのコードを書くよ!
RustでgRPCサーバーを作るときは、warpとかactic-webじゃなくてtonicを使うみたい!
Cargo.tomlファイル↓
[package]
name = "rust-grpc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tonic = "0.11.0"
prost = "0.12.3"
tokio = { version = "1.36.0", features = ["full"] }
[build-dependencies]
tonic-build = "0.11.0"
[[bin]]
name = "greeter_server"
path = "src/main.rs"
[build]
# `build.rs`をビルドスクリプトとして指定
script = "build.rs"
これでprotoファイルからコンパイルしたり、gRPC通信が書けるよ!
protoファイルからRustのコードを生成する!
以下のコード↓でgreeter.protoファイルから、Rustの型定義とgRPCサービス(greeter)の実装を含むコードを生成できるよ!
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/greeter.proto")?;
Ok(())
}
このコードはcargo build
するときに自動で実行されるんだ〜
サーバーのコードを書く!!
gRPCサーバーの起動とgreeterサービスの実装をmain.rsに書いていくよ!
まずは、protoから型とかをインポートしよー!
use tonic::{transport::Server, Request, Response, Status};
// greeter.protoから自動生成されたRustコードを読み込む
pub mod greeter {
tonic::include_proto!("greeter"); // package名に対応
}
greeterから型をインポート
use greeter::{
greeter_server::{Greeter, GreeterServer},
GoodbyeReply, GoodbyeRequest, HelloReply, HelloRequest,
};
protoから型をインポートしたら、greeterサービスのメソッド(say_helloとsay_goodbye)を実装するよ〜
#[derive(Default)]
pub struct MyGreeter {}
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<HelloRequest>, // リクエストの型
) -> Result<Response<HelloReply>, Status> { // レスポンスとエラーの型
let reply = greeter::HelloReply {
message: format!("Hello, {}!", request.into_inner().name),
};
Ok(Response::new(reply))
}
async fn say_goodbye(
&self,
request: Request<GoodbyeRequest>, // リクエストの型
) -> Result<Response<GoodbyeReply>, Status> { // レスポンスとエラーの型
let reply = greeter::GoodbyeReply {
message: format!("Goodbye, {}!", request.into_inner().name),
};
Ok(Response::new(reply))
}
}
最後にサーバーを実行して、say_helloとsay_goodbyeを組み込む!
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let greeter = MyGreeter::default();
println!("GreeterServer listening on {}", addr);
Server::builder()
.add_service(GreeterServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}
これでgRPCサーバーはできたはず!
起動してみてね↓
cargo run
gRPCを実行して、BloomRPCで確認するぞ!
起動してもちゃんと機能するのか確認したい!
そんなときにBloomRPCアプリで動作確認が秒でできてすごかった
BloomRPCアプリのインストール
brew install --cask bloomrpc
bloomrpcを起動したらprotoファイルを読み込もう!!
「+」ボタン↓を押して、
今回作ったプロジェクトの「greeter.proto」を選んでね↓
そしたら、左のパネルに出てきた「SayHello」か「SayGoodbye」をクリックしてタブを開こ!
「0.0.0.0:3009」って書いてあるところは、今回のプロジェクトに合わせて「localhost:50051」に書き換えてね!
んで、中央の緑の「▶️」ボタンを押すとレスポンスが表示されるはずだよ!
終わりに
なんかうまくいかないとかあったら言ってね!
また、間違いやご不明点があればコメントいただければ幸いです😊
ヌギーのSNS(連絡先など)
Discussion