这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
尝试用tonic写后端的gRPC
Dependencies
Setup
和初识axum时一样,先把tonic的default features禁了,不够再加。
Rust不在protobuf的官方支持中,因此直接看tonic的文档。
tonic的文档跳转到了tonic-build。
由于tonic-build是build dependency,因此没有加no default。
Steps
one
先开新仓库用来专门存proto。
auth.proto
syntax = "proto3";
package mini_tiktok.auth.proto;
message AuthRequest {
string user_id = 1;
string token = 2;
}
message TokenRequest {
string username = 1;
string password = 2;
}
message AuthResponse {
enum AuthStatusCode {
SUCCESS = 0;
FAIL = 1;
}
AuthStatusCode status_code = 1;
}
message TokenResponse {
enum TokenStatusCode {
SUCCESS = 0;
FAIL = 1;
}
TokenStatusCode status_code = 1;
string token = 2;
}
service AuthService {
rpc Auth (AuthRequest) returns (AuthResponse);
rpc RetriveToken (TokenRequest) returns (TokenResponse);
}
two
把proto加到submodule。 位置为Auth/proto。
Note: 最好先把proto仓库提交了再add,不然没commit会add失败。
或者直接把仓库clone到子路径,提交push完了再add
然后照着文档写build script。
build.rs
fn main() -> std::io::Result<()> {
tonic_build::configure()
.build_client(false)
.compile(&["proto/auth.proto"], &["proto"])
}
Note: 记得下protoc,然后把protoc塞PATH里
cargo build成功执行,没有错误。
three
怎么把生成的源码加到程序中?
在tonic文档里面居然没找到。
tonic-build文档里也没有。
呃呃呃
看看prost咋弄的。
转到prost-build。
终于找到了方法。
// Include the `items` module, which is generated from items.proto.
// It is important to maintain the same structure as in the proto.
pub mod snazzy {
pub mod items {
include!(concat!(env!("OUT_DIR"), "/snazzy.items.rs"));
}
}
use snazzy::items;
pub fn create_large_shirt(color: String) -> items::Shirt {
let mut shirt = items::Shirt::default();
shirt.color = color;
shirt.set_size(items::shirt::Size::Large);
shirt
}
直接往裸rs塞个include试试。
proto.rs
include!(concat!(env!("OUT_DIR"), "/mini_tiktok.auth.proto.rs"));
cargo build一下。
出现了巨量的错误。(错误过多就不贴了)
看来要加包了。
直接往dep塞prost(禁default feature)。
build还是报错。
看看文档。
把tonic的transport、codegen、prost全加上得了。
build的时候多了很多包。
为什么会有axum
但是编译通过了!
four
没有four了。今天就到这里
Summary
实际上我还翻了半天的protobuf文档看proto3的语法和style guide。
翻的时候又去找了半天well-known types的import路径。
不知道找了多久,最后终于在issue里面找到了。
令人失望的是,这个2017年开的issue到现在还是open的。
虽然最后我并没有用这些types。
Appendix
后来我发现tonic有个macro叫include_proto。
proto.rs
tonic::include_proto!("mini_tiktok.auth.proto");
License
This work is licensed under CC BY-SA 4.0