How to get an endpoint's actual response in a middleware? #2834
-
Hi, I'm new to Actix Web and Rust in general and I'm trying to create a custom middleware to cache endpoint responses using Redis. My approach is that I'll retrieve the endpoint's response and store it in redis. impl<'a, S, B> Service<ServiceRequest> for SomethingMiddleware<S>
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static + std::fmt::Debug,
{
type Response = ServiceResponse<B>;
type Error = Error;
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
forward_ready!(service);
fn call(&self, req: ServiceRequest) -> Self::Future {
println!("Hi from start. You requested: {}", req.path());
let req_path = req.path().to_owned();
let req_queries = format!("?{}", req.query_string().to_owned());
let redis_key = format!("{req_path}{req_queries}");
let redis_client = req.app_data::<web::Data<redis::Client>>().unwrap();
let mut redis_conn = redis_client.get_connection().unwrap();
let fut = self.service.call(req);
Box::pin(async move {
let res = fut.await?;
let _: Result<(), redis::RedisError> =
redis_conn.set(&redis_key, &format!("{:?}", res.response().body()));
println!("Hi from response");
println!("{:#?}", res.response().body());
Ok(res)
})
}
} Currently I've successfully stored the response, but it's in the Debug form. How do I get the actual response body? I'm using |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
Since it requires ownership of the body, you'll need to "replace" the body, read it and then, put the body back later. type Response = ServiceResponse<Bytes>;
// [snip]
let (req, res) = res.into_parts(());
let (res, body) = res.into_parts();
let body_bytes = actix_web::body::to_bytes(body).await.ok().unwrap();
println!("{:?}", body_bytes);
let res = res.set_body(body_bytes);
let res = ServiceResponse::new(req, res); |
Beta Was this translation helpful? Give feedback.
actix_web::body::to_bytes().await
is made for this purpose but you should only use this in a middleware if you are confident that no responses use streaming bodies.Since it requires ownership of the body, you'll need to "replace" the body, read it and then, put the body back later.