Skip to content

Mixing buffered and streaming responses #805

@GabrielBianconi

Description

@GabrielBianconi

I'm trying to build a Lambda with routes for both streaming (Axum SSE) and regular (buffered) handlers.

I've tried using run_with_streaming_response, which works as expected for the streaming handlers but sends an empty response for regular handlers.

With run, the regular handler works as expected but it also buffers the streaming handler before responding.

Here's a minimal example:

use axum::{
    response::{
        sse::{Event, Sse},
        IntoResponse,
    },
    routing::get,
    Router,
};
use futures::stream::{self, Stream};
use std::{convert::Infallible, time::Duration};
use tokio_stream::StreamExt as _;

async fn regular_handler() -> impl IntoResponse {
    "Buffered hello world!"
}

async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
    let stream = stream::repeat_with(|| Event::default().data("Streamed hello world!"))
        .map(Ok)
        .throttle(Duration::from_secs(1))
        .take(5);

    Sse::new(stream).keep_alive(
        axum::response::sse::KeepAlive::new()
            .interval(Duration::from_secs(1))
            .text("keep-alive-text"),
    )
}

#[tokio::main]
async fn main() -> Result<(), lambda_http::Error> {
    let app = Router::new()
        .route("/a", get(regular_handler))
        .route("/b", get(sse_handler));

    // lambda_http::run(app).await // --> /a works fine, but also buffers /b before responding

    lambda_http::run_with_streaming_response(app).await // --> /a returns an empty reply from server, /b streams as expected
}

Is there a way to set up a Lambda that accepts both types of handlers?

Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions