have an Axum server where one of the routes accesses an S3 storage and returns a JSON file based on the request. The current implementation downloads the file to the server via the rust-s3
crate and returns Result<Json<Value>, StatusCode>
from the Axum route.
This works, but I want to make it more efficient by streaming the file directly from S3 to the client.
I have the following code to get a stream from S3:
/// Downloads a file from an S3 bucket as a stream.
/// This function returns a stream of the requested file from the specified S3 bucket.
pub async fn download_stream(bucket_name: &str, remote_path: &str) -> Result<ResponseDataStream> {
// Create S3 region and credentials from environment variables.
...
// Connect to the S3 bucket.
let bucket = Bucket::new(bucket_name, region, credentials)?;
// Fetch the file from the S3 bucket as a stream.
let object_stream = bucket.get_object_stream(remote_path).await?;
Ok(object_stream)
}
The return value is ResponseDataStream.
Now, I want to return the stream from axum
route:
pub async fn do_analysis(
Path((sha, id)): Path<(String, String)>,
) -> Result<Json<Value>, StatusCode> {
...
match s3::download_stream(&s3_bucket, &dynamic).await {
Ok(stream) => Ok(Json(stream)), // invalid code
Err(_) => Err(StatusCode::NOT_FOUND),
}
}
I'm not sure if the return type is correct or what to return from the do_analysis
route. What's the best way to implement this logic?