diff --git a/lambda-http/src/lib.rs b/lambda-http/src/lib.rs
index cea99750..d6f8dbb0 100644
--- a/lambda-http/src/lib.rs
+++ b/lambda-http/src/lib.rs
@@ -101,7 +101,7 @@ use std::{
};
mod streaming;
-pub use streaming::run_with_streaming_response;
+pub use streaming::{into_streaming_response, run_with_streaming_response};
/// Type alias for `http::Request`s with a fixed [`Body`](enum.Body.html) type
pub type Request = http::Request
;
diff --git a/lambda-http/src/streaming.rs b/lambda-http/src/streaming.rs
index a93408b4..67d772c0 100644
--- a/lambda-http/src/streaming.rs
+++ b/lambda-http/src/streaming.rs
@@ -3,7 +3,14 @@ use bytes::Bytes;
pub use http::{self, Response};
use http_body::Body;
use lambda_runtime::Diagnostic;
-pub use lambda_runtime::{self, tower::ServiceExt, Error, LambdaEvent, MetadataPrelude, Service, StreamResponse};
+pub use lambda_runtime::{
+ self,
+ tower::{
+ util::{MapRequest, MapResponse},
+ ServiceExt,
+ },
+ Error, LambdaEvent, MetadataPrelude, Service, StreamResponse,
+};
use std::{
fmt::Debug,
pin::Pin,
@@ -11,12 +18,21 @@ use std::{
};
use tokio_stream::Stream;
-/// Starts the Lambda Rust runtime and stream response back [Configure Lambda
-/// Streaming Response](https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html).
+/// Converts a handler into a streaming-compatible service for use with AWS
+/// Lambda.
///
-/// This takes care of transforming the LambdaEvent into a [`Request`] and
-/// accepts [`http::Response`] as response.
-pub async fn run_with_streaming_response<'a, S, B, E>(handler: S) -> Result<(), Error>
+/// This function wraps a `Service` implementation, transforming its input and
+/// output to be compatible with AWS Lambda's streaming response feature. It
+/// provides the necessary middleware to handle `LambdaEvent` requests and
+/// converts the `http::Response` into a `StreamResponse` containing a metadata
+/// prelude and body stream.
+#[allow(clippy::type_complexity)]
+pub fn into_streaming_response<'a, S, B, E>(
+ handler: S,
+) -> MapResponse<
+ MapRequest) -> Request>,
+ impl FnOnce(Response) -> StreamResponse> + Clone,
+>
where
S: Service, Error = E>,
S::Future: Send + 'a,
@@ -25,13 +41,13 @@ where
B::Data: Into + Send,
B::Error: Into + Send + Debug,
{
- let svc = ServiceBuilder::new()
+ ServiceBuilder::new()
.map_request(|req: LambdaEvent| {
let event: Request = req.payload.into();
event.with_lambda_context(req.context)
})
.service(handler)
- .map_response(|res| {
+ .map_response(|res: Response| {
let (parts, body) = res.into_parts();
let mut prelude_headers = parts.headers;
@@ -54,8 +70,25 @@ where
metadata_prelude,
stream: BodyStream { body },
}
- });
+ })
+}
+/// Starts the Lambda Rust runtime and stream response back [Configure Lambda
+/// Streaming
+/// Response](https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html).
+///
+/// This takes care of transforming the LambdaEvent into a [`Request`] and
+/// accepts [`http::Response`] as response.
+pub async fn run_with_streaming_response<'a, S, B, E>(handler: S) -> Result<(), Error>
+where
+ S: Service, Error = E>,
+ S::Future: Send + 'a,
+ E: Debug + Into,
+ B: Body + Unpin + Send + 'static,
+ B::Data: Into + Send,
+ B::Error: Into + Send + Debug,
+{
+ let svc = into_streaming_response(handler);
lambda_runtime::run(svc).await
}