xref: /tonic/examples/src/interceptor/client.rs (revision 4e578b50)
1 use hello_world::greeter_client::GreeterClient;
2 use hello_world::HelloRequest;
3 use tonic::{
4     codegen::InterceptedService,
5     service::Interceptor,
6     transport::{Channel, Endpoint},
7     Request, Status,
8 };
9 
10 pub mod hello_world {
11     tonic::include_proto!("helloworld");
12 }
13 
14 #[tokio::main]
main() -> Result<(), Box<dyn std::error::Error>>15 async fn main() -> Result<(), Box<dyn std::error::Error>> {
16     let channel = Endpoint::from_static("http://[::1]:50051")
17         .connect()
18         .await?;
19 
20     let mut client = GreeterClient::with_interceptor(channel, intercept);
21 
22     let request = tonic::Request::new(HelloRequest {
23         name: "Tonic".into(),
24     });
25 
26     let response = client.say_hello(request).await?;
27 
28     println!("RESPONSE={:?}", response);
29 
30     Ok(())
31 }
32 
33 /// This function will get called on each outbound request. Returning a
34 /// `Status` here will cancel the request and have that status returned to
35 /// the caller.
intercept(req: Request<()>) -> Result<Request<()>, Status>36 fn intercept(req: Request<()>) -> Result<Request<()>, Status> {
37     println!("Intercepting request: {:?}", req);
38     Ok(req)
39 }
40 
41 // You can also use the `Interceptor` trait to create an interceptor type
42 // that is easy to name
43 struct MyInterceptor;
44 
45 impl Interceptor for MyInterceptor {
call(&mut self, request: tonic::Request<()>) -> Result<tonic::Request<()>, Status>46     fn call(&mut self, request: tonic::Request<()>) -> Result<tonic::Request<()>, Status> {
47         Ok(request)
48     }
49 }
50 
51 #[allow(dead_code, unused_variables)]
using_named_interceptor() -> Result<(), Box<dyn std::error::Error>>52 async fn using_named_interceptor() -> Result<(), Box<dyn std::error::Error>> {
53     let channel = Endpoint::from_static("http://[::1]:50051")
54         .connect()
55         .await?;
56 
57     let client: GreeterClient<InterceptedService<Channel, MyInterceptor>> =
58         GreeterClient::with_interceptor(channel, MyInterceptor);
59 
60     Ok(())
61 }
62 
63 // Using a function pointer type might also be possible if your interceptor is a
64 // bare function that doesn't capture any variables
65 #[allow(dead_code, unused_variables, clippy::type_complexity)]
using_function_pointer_interceptro() -> Result<(), Box<dyn std::error::Error>>66 async fn using_function_pointer_interceptro() -> Result<(), Box<dyn std::error::Error>> {
67     let channel = Endpoint::from_static("http://[::1]:50051")
68         .connect()
69         .await?;
70 
71     let client: GreeterClient<
72         InterceptedService<Channel, fn(tonic::Request<()>) -> Result<tonic::Request<()>, Status>>,
73     > = GreeterClient::with_interceptor(channel, intercept);
74 
75     Ok(())
76 }
77