Skip to content

Commit 4fafbef

Browse files
authored
chore: refactor Volo getting-started doc for better usability (cloudwego#852)
1 parent 8be9a59 commit 4fafbef

File tree

24 files changed

+1344
-1447
lines changed

24 files changed

+1344
-1447
lines changed

content/en/docs/volo/volo-grpc/getting-started/_index.md

Lines changed: 334 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,338 @@
22
title: "Getting Started"
33
linkTitle: "Getting Started"
44
weight: 1
5-
description: >
6-
5+
keywords: ["Volo", "gRPC", "Tutorial", "Install"]
6+
description: "This document covers the preparation of the development environment, quick start and basic tutorials of Volo-gRPC."
77
---
8+
9+
## Part 1. Install the CLI Tool
10+
11+
Volo provides CLI tools of the same name for initializing projects, managing IDLs, and more. To install Volo tool, you need to switch to `nightly` channel and run the following command:
12+
13+
```bash
14+
rustup default nightly
15+
```
16+
```bash
17+
cargo install volo-cli
18+
```
19+
20+
Then run:
21+
22+
```bash
23+
volo help
24+
```
25+
26+
You should see something like the following:
27+
```bash
28+
USAGE:
29+
volo [OPTIONS] <SUBCOMMAND>
30+
31+
OPTIONS:
32+
-h, --help Print help information
33+
-n, --entry-name <ENTRY_NAME> The entry name, defaults to 'default'. [default: default]
34+
-v, --verbose Turn on the verbose mode.
35+
-V, --version Print version information
36+
37+
SUBCOMMANDS:
38+
help Print this message or the help of the given subcommand(s)
39+
idl manage your idl
40+
init init your project
41+
```
42+
43+
## Part 2. Create a gRPC Server
44+
45+
Volo-gRPC is an RPC framework so that the bottom layer requires two major functions: Serialization and Transport.
46+
47+
IDL is short for `Interface Definition Language`.
48+
49+
### 2.1 Why IDL
50+
51+
If we want to do RPC, we need to know what interface is for the server, what parameters to pass, and what the return value is,
52+
just like two people talking to each other, we need to make sure we are speaking the same language and doing the same thing.
53+
54+
At this time, we need to use IDL to specify the protocol for both sides, just like when writing code, we need to know the function signature while calling a function.
55+
56+
Protobuf IDL is a full-stack RPC solution for cross-language, the specific syntax can be seen in [protocol-buffers/docs/proto3](https://developers.google.com/protocol-buffers/docs/proto3).
57+
58+
### 2.2 Write IDL
59+
60+
To create a gRPC project, we need to write a protobuf IDL at first.
61+
62+
In your working directory, execute the following command:
63+
64+
```bash
65+
mkdir volo-example && cd volo-example
66+
```
67+
```bash
68+
mkdir idl && vim idl/volo_example.proto
69+
```
70+
71+
Then, enter the following content:
72+
73+
```protobuf
74+
syntax = "proto3";
75+
package volo.example;
76+
77+
message Item {
78+
int64 id = 1;
79+
string title = 2;
80+
string content = 3;
81+
82+
map<string, string> extra = 10;
83+
}
84+
85+
message GetItemRequest {
86+
int64 id = 1;
87+
}
88+
89+
message GetItemResponse {
90+
Item item = 1;
91+
}
92+
93+
service ItemService {
94+
rpc GetItem(GetItemRequest) returns (GetItemResponse);
95+
}
96+
```
97+
98+
After saving and exiting, we execute the following command:
99+
100+
```bash
101+
volo init --includes=idl volo-example idl/volo_example.proto
102+
```
103+
104+
**Here we use the `init` command, followed by the name of our project, which means we need to generate template code. At the end, you need to specify an IDL used by the server.**
105+
106+
If you only need to add an IDL (such as the client IDL) without generating a template, do as follows:
107+
108+
```bash
109+
volo idl add idl/volo_example.proto
110+
```
111+
112+
| What's more, the volo tool also supports downloading IDL from git and then generating code, such as:
113+
114+
```bash
115+
volo idl add -g [email protected]:org/repo.git -r main /path/to/your/idl.proto
116+
```
117+
118+
| You may directly enter volo to see the detailed usage ~ next back to the topic ~
119+
120+
At this point, our entire directory structure looks like this:
121+
122+
```bash
123+
.
124+
├── Cargo.toml
125+
├── idl
126+
│ └── volo_example.proto
127+
├── rust-toolchain.toml
128+
├── src
129+
│ ├── bin
130+
│ │ └── server.rs
131+
│ └── lib.rs
132+
└── volo-gen
133+
├── Cargo.toml
134+
├── build.rs
135+
├── src
136+
│ └── lib.rs
137+
└── volo.yml
138+
```
139+
140+
Then we open `src/lib.rs` and add the method implementation to the `impl` block. The resulting code should look like this:
141+
142+
```rust
143+
pub struct S;
144+
145+
impl volo_gen::volo::example::ItemService for S {
146+
// This is the part of the code we need to add
147+
async fn get_item(
148+
&self,
149+
_req: volo_grpc::Request<volo_gen::volo::example::GetItemRequest>,
150+
) -> core::result::Result<volo_grpc::Response<volo_gen::volo::example::GetItemResponse>, volo_grpc::Status>
151+
{
152+
Ok(volo_grpc::Response::new(Default::default()))
153+
}
154+
}
155+
```
156+
157+
Then execute:
158+
159+
```bash
160+
cargo update && cargo build
161+
```
162+
163+
At this point, You will find `volo_gen.rs` file under [OUT_DIR Directory](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts).
164+
165+
Then execute the following command to get our server running:
166+
167+
```bash
168+
cargo run --bin server
169+
```
170+
171+
At this point, we have our server running!
172+
173+
## Part 3. Create a Client
174+
175+
In the previous section, we wrote a server, now let's write a client and call the server.
176+
177+
First, create a file called `src/bin/client.rs` and type the following:
178+
179+
```rust
180+
use lazy_static::lazy_static;
181+
use std::net::SocketAddr;
182+
183+
lazy_static! {
184+
static ref CLIENT: volo_gen::volo::example::ItemServiceClient = {
185+
let addr: SocketAddr = "[::1]:8080".parse().unwrap();
186+
volo_gen::volo::example::ItemServiceClientBuilder::new("volo-example")
187+
.address(addr)
188+
.build()
189+
};
190+
}
191+
192+
#[volo::main]
193+
async fn main() {
194+
tracing_subscriber::fmt::init();
195+
let req = volo_gen::volo::example::GetItemRequest { id: 1024 };
196+
let resp = CLIENT.get_item(req).await;
197+
match resp {
198+
Ok(info) => tracing::info!("{:?}", info),
199+
Err(e) => tracing::error!("{:?}", e),
200+
}
201+
}
202+
```
203+
204+
Then add the required dependencies to the `Cargo.toml` file, which looks like this:
205+
206+
```toml
207+
[package]
208+
name = "volo-example"
209+
version = "0.1.0"
210+
edition = "2021"
211+
212+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
213+
214+
[dependencies]
215+
anyhow = "1"
216+
async-trait = "0.1"
217+
lazy_static = "1"
218+
tokio = { version = "1", features = ["full"] }
219+
tracing = "0.1"
220+
prost = "0.11"
221+
tracing-subscriber = "0.3"
222+
223+
pilota = "*"
224+
volo = "*" # we recommend to use the latest framework version for new features and bug fixes
225+
volo-grpc = "*" # we recommend to use the latest framework version for new features and bug fixes
226+
227+
volo-gen = { path = "./volo-gen" }
228+
229+
[profile.release]
230+
opt-level = 3
231+
debug = true
232+
debug-assertions = false
233+
overflow-checks = false
234+
lto = true
235+
panic = 'unwind'
236+
incremental = false
237+
codegen-units = 1
238+
rpath = false
239+
240+
[workspace]
241+
members = ["volo-gen"]
242+
resolver = "2"
243+
```
244+
245+
Then, **create a new terminal** and run the following command to start our server:
246+
247+
```bash
248+
cargo run --bin server
249+
```
250+
251+
Finally, we go back to the current directory and execute the following command, and we can see that the execution is successful:
252+
253+
```bash
254+
cargo run --bin client
255+
```
256+
257+
## Part 4. Add a Middleware
258+
259+
Next, let's look at how to add middleware to Volo.
260+
261+
For example, if we need a middleware that prints out the received requests, the returned responses and the elapsed time, we could write a Service in `lib.rs`:
262+
263+
```rust
264+
#[derive(Clone)]
265+
pub struct LogService<S>(S);
266+
267+
#[volo::service]
268+
impl<Cx, Req, S> volo::Service<Cx, Req> for LogService<S>
269+
where
270+
Req: Send + 'static,
271+
S: Send + 'static + volo::Service<Cx, Req> + Sync,
272+
Cx: Send + 'static,
273+
{
274+
async fn call(&self, cx: &mut Cx, req: Req) -> Result<S::Response, S::Error> {
275+
let now = std::time::Instant::now();
276+
let resp = self.0.call(cx, req).await;
277+
tracing::info!("Request took {}ms", now.elapsed().as_millis());
278+
resp
279+
}
280+
}
281+
```
282+
283+
Then we wrap a Layer around the Service:
284+
285+
```rust
286+
pub struct LogLayer;
287+
288+
impl<S> volo::Layer<S> for LogLayer {
289+
type Service = LogService<S>;
290+
291+
fn layer(self, inner: S) -> Self::Service {
292+
LogService(inner)
293+
}
294+
}
295+
```
296+
297+
Finally, we add this Layer to client and server:
298+
299+
```rust
300+
use volo_example::LogLayer;
301+
302+
// client.rs
303+
static ref CLIENT: volo_gen::volo::example::ItemServiceClient = {
304+
let addr: SocketAddr = "[::1]:8080".parse().unwrap();
305+
volo_gen::volo::example::ItemServiceClientBuilder::new("volo-example")
306+
.layer_outer(LogLayer)
307+
.address(addr)
308+
.build()
309+
};
310+
311+
// server.rs
312+
Server::new()
313+
.add_service(ServiceBuilder::new(volo_gen::volo::example::ItemServiceServer::new(S)).build())
314+
.layer_front(LogLayer)
315+
.run(addr)
316+
.await
317+
.unwrap();
318+
```
319+
320+
At this point, it prints out how long the request took at the INFO log level.
321+
322+
## Part 5. What's Next?
323+
324+
Congratulations, you've read this far! At this point, we've basically learned how to use Volo, and we're ready to use Volo to kick off our Rust journey
325+
326+
Next, you may need to select the right components, put them together, and interface with your system.
327+
328+
The related ecosystem maintained by Volo will be located in: https://github.com/volo-rs, we are working to build our ecosystem, and welcome everyone to join us ~
329+
330+
If there is a dire lack of components, you are welcomed to raise an issue in: https://github.com/cloudwego/volo, we will support it as soon as possible.
331+
332+
In the meantime, welcome to join our Lark user group and share your experience with us about Volo.
333+
334+
<div align="center">
335+
<img src="/img/docs/feishu_group_volo.png" width = "400" alt="Volo_feishu" />
336+
</div>
337+
<br/><br/>
338+
339+
Looking forward to your unique work created with Volo.

content/en/docs/volo/volo-grpc/getting-started/part_1.md

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)