hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
9.69k stars 990 forks source link

How does tonic library dynamically set up custom middleware #1800

Open tgy3300 opened 2 months ago

tgy3300 commented 2 months ago
pub struct GrpcStruct <F> 
where
    F: tonic::service::interceptor::Interceptor + Clone + Send + Sync + 'static,
{
    middleware: Vec<F>,
}

Setting the layer manually is fine

        let ss = self.middleware[0].clone();
        let ss1 = self.middleware[1].clone();
        let ss2 = self.middleware[2].clone();

        tonic::transport::Server::builder()
            .layer(interceptor(ss))
            .layer(interceptor(ss1))
            .layer(interceptor(ss2))
            .add_service(srv)
            .serve(address)
            .await
            .unwrap();

// But change to dynamic add, will report an error, the error at the bottom

        let mut app = tonic::transport::Server::builder();
        for mid in self.middleware.iter() {
            app = app.layer(interceptor(mid.clone()));
        }
        app.add_service(srv).serve(address).await.unwrap();

Report an error: image

alexrudy commented 1 month ago

Middleware in tower is statically typed - so you can't add to it dynamically like this. You might be able to use a lot of boxed services to get around this. See BoxLayer for some inspiration and a better explanation of why this won't work.