Gateway microservice on Actix-Web. Is it possible to put a grpc client in the Application State and then pull it into the handler? To avoid creating it in every handler. If possible, how can I do it?
How do I specify the type?
[main.rs]
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
...
let channel = Channel::from_static("http://127.0.0.1:5051").connect().await.unwrap();
let mut user_client = UserServiceClient::with_interceptor(channel, user_client_handler);
let shared_data = web::Data::new(State {
user_client: **user_client**,
});
...
}
fn user_client_handler(mut req: Request<()>) -> Result<Request<()>, Status> {
let token = AsciiMetadataValue::from_static("...");
req.metadata_mut().insert("authorization", token);
Ok(req)
}
pub struct State {
pub user_client: **?**,
}
[user_handler.rs]
pub async fn get_users(path: web::Path<(i64,i64)>, state: web::Data<State>,) -> Result<HttpResponse, AppError> {
let request = tonic::Request::new(...);
let mut client = UserServiceClient::connect("http://127.0.0.1:5051").await?;
let mut grpc_response = client.list_users(request).await?.into_inner();
let json_response: UsersListResponse = grpc_response.into();
Ok(HttpResponse::Ok().json(json_response))
}
Updated Error message:
error[E0308]: mismatched types
--> src/main.rs:59:22
|
59 | user_client: user_client,
| ^^^^^^^^^^^ expected fn pointer, found fn item
|
= note: expected struct `UserServiceClient<tonic::service::interceptor::InterceptedService<_, fn(tonic::Request<_>) -> Result<_, _>>>`
found struct `UserServiceClient<tonic::service::interceptor::InterceptedService<_, fn(tonic::Request<_>) -> Result<_, _> {user_client_handler}>>`
UPDATE 2024.03.06
//[main.rs]
let channel = Channel::from_static("http://127.0.0.1:5051").connect().await.unwrap();
let mut user_client = UserServiceClient::with_interceptor(channel, token_interceptor);
let shared_data = web::Data::new(State {
user_client: ???,
});
//[state.rs]
pub struct State {
pub user_client: UserServiceClient<Box<dyn Fn(Request<()>) -> Result<Request<()>,Status>>>,
//pub user_client: UserServiceClient<InterceptedService<Channel, fn(Request<()>) -> Result<Request<()>, Status>>>,
}
Error
error[E0308]: mismatched types
--> src/main.rs:58:22
|
58 | user_client: user_client,
| ^^^^^^^^^^^ expected `UserServiceClient<Box<dyn Fn(...) -> ...>>`, found `UserServiceClient<InterceptedService<..., ...>>`
|
= note: expected struct `UserServiceClient<Box<(dyn Fn(tonic::Request<()>) -> Result<tonic::Request<()>, tonic::Status> + 'static)>>`
found struct `UserServiceClient<tonic::service::interceptor::InterceptedService<Channel, fn(tonic::Request<()>) -> Result<tonic::Request<()>, tonic::Status> {token_interceptor}>>`
Change the closure to a seperate function
This is because in your definition you used function pointer
Notice the lower case "fn", if you want to use closure you will need to use
Update:
You'll have to either use Generics T or Box dyn