Writer based ResponseBody
mineichen opened this issue · comments
- I have looked for existing issues (including closed) about this
Feature Request
Motivation
I'm using async_zip to send data directly to the client. async_zip::core::ZipFileWriter::new
accepts a param, which implements AsyncWrite. Afterwards, i can asynchronously add files to the ZipFileWriter, and the encoded/compressed data is written to the underlying writer. Unfortunately, I couldn't get a hand on a writer for the HttpBody.
Proposal
I came up with a new IntoResponse type, which accepts a closure that returns a future. As long as the future is not finished, it's able to write data to the writer. You can find a naive implementation here. The usage of that type looks like this:
IoStreamBody::with_writer(move |mut w| {
async move {
w.write_all(b"Hello").await?;
Ok(())
}
}),
This will allow easy integration with async_zip and it will potentially be easier to imlement allocation-free data-streams, as we never need to represent the data to be returned as a owned byte-slice.
Alternatives
Just leave this to the user, as it can be implemented today.
I don't know, how important backward compatibility is... Maybe It could be implemented with AsyncFn instead?
Such a IntoResponse-Type could also life in the axum-extras project. The Error type should most likely not be anyhow::Error (as in the poc implementation).
You don't need a new type, you can just use ReaderStream to convert your Reader
into a Stream
and then Body::from_stream
.
Does that solve your issue?
It could be part of the implementation, but there is more to it.
I don't just have a AsyncRead, but I have to create one, e.g. with piper. But now I have drive the future which fills the pipe somewhere. In my implementation I do this as part of the Stream( the easiest way is, to just spawn a tokio task, but in a complete implementation I have to handle Errors/Panics of this task so it can be related to the Request and is not just a "global error").
I aggree, that this doesn't have to be directly related to axum, but outside axum, we need to go through a indirection (e.g. Piper), but axum has the possibility to expose the writer with access to the RequestSocket, if it's implemented by axum itself and not in axum-extra.
It would be another paradigm, and other Languages/Frameworks (e.g. Dotnet) allow you to write to the http-body instead of returning a value from the handler which is then written by the framework. It would be nice to have something like that, because it wasn't obvious to me how I can use AsyncFileWriter without a intermediate Buffer. A junior dev might even think, that this is not possible with axum.