axum
axum copied to clipboard
Parse multipart body into a struct like Json<SomeStruct>
Feature Request
Motivation
Similar to how a request body can be parsed into struct from Json, it would be useful to have an extractor to do the same for multipart requests. Currently the extractor needs used manually to read individual fields
Proposal
A new extractor perhaps
Alternatives
Currently I will need to do this in user code
Can you explain what you use case is for this?
For future readers, here is how to do it today:
async fn upload_json(mut multipart: Multipart) -> Result<(), StatusCode> {
#[derive(serde::Deserialize)]
struct Payload {
foo: String,
}
while let Some(field) = multipart
.next_field()
.await
.map_err(|_| StatusCode::BAD_REQUEST)?
{
// might also wanna check `field.name()`, `field.file_name()`, or `field.headers()`
let bytes = field.bytes().await.map_err(|_| StatusCode::BAD_REQUEST)?;
let payload: Payload =
serde_json::from_slice(&bytes).map_err(|_| StatusCode::BAD_REQUEST)?;
}
Ok(())
}
Since you need to check the name
, etc, I'm not sure how to make this simpler or if doing so is worth it.
I think a Form
equivalent for multipart forms, if we add it at all, should come with a big warning that it should only be used when the fields are pretty small / you need to hold them all in memory at once anyways, as the existing Multipart
extractor is much more efficient when passing through the fields to some output in a streaming manner is possible, or when multiple large fields can be handled individually.
I'll close this for now. Not clear what the use case is so @affanshahid please comment if you can provide more context.
I'd like to chime in, because this is something that's biting me at work currently.
In other frameworks (Spring Boot with Java comes to mind personally) it is possible and fairly common to map all the fields of a multipart/form-data
body to a single object.
It is of course a tradeoff and the current extractor is admittedly much more efficient, but reading, validating and parsing every field can get a little too verbose when dealing with more than a couple of fields.
Nothing is stopping you from writing your own though.
Oh yeah, of course (and now I'm curious to try that out). I was just saying it's a usecase I've seen often enough.