pub struct Multipart { /* private fields */ }
multipart
only.Expand description
Extractor that parses multipart/form-data
requests (commonly used with file uploads).
⚠️ Since extracting multipart form data from the request requires consuming the body, the
Multipart
extractor must be last if there are multiple extractors in a handler.
See “the order of extractors”
§Example
use axum::{
routing::post,
Router,
};
use axum_extra::extract::Multipart;
async fn upload(mut multipart: Multipart) {
while let Some(mut field) = multipart.next_field().await.unwrap() {
let name = field.name().unwrap().to_string();
let data = field.bytes().await.unwrap();
println!("Length of `{}` is {} bytes", name, data.len());
}
}
let app = Router::new().route("/upload", post(upload));
§Field Exclusivity
A Field
represents a raw, self-decoding stream into multipart data. As such, only one
Field
from a given Multipart instance may be live at once. That is, a Field
emitted by
next_field()
must be dropped before calling next_field()
again. Failure to do so will
result in an error.
use axum_extra::extract::Multipart;
async fn handler(mut multipart: Multipart) {
let field_1 = multipart.next_field().await;
// We cannot get the next field while `field_1` is still alive. Have to drop `field_1`
// first.
let field_2 = multipart.next_field().await;
assert!(field_2.is_err());
}
In general you should consume Multipart
by looping over the fields in order and make sure not
to keep Field
s around from previous loop iterations. That will minimize the risk of runtime
errors.
§Differences between this and axum::extract::Multipart
axum::extract::Multipart
uses lifetimes to enforce field exclusivity at compile time, however
that leads to significant usability issues such as Field
not being 'static
.
axum_extra::extract::Multipart
instead enforces field exclusivity at runtime which makes
things easier to use at the cost of possible runtime errors.
Implementations§
Source§impl Multipart
impl Multipart
Sourcepub async fn next_field(&mut self) -> Result<Option<Field>, MultipartError>
pub async fn next_field(&mut self) -> Result<Option<Field>, MultipartError>
Yields the next Field
if available.
Sourcepub fn into_stream(
self,
) -> impl Stream<Item = Result<Field, MultipartError>> + Send + 'static
pub fn into_stream( self, ) -> impl Stream<Item = Result<Field, MultipartError>> + Send + 'static
Convert the Multipart
into a stream of its fields.