File uploads
Extract typed file and text fields from multipart forms and configure size limits.
MultipartForm<T> separates a multipart body into text and file fields. This path uses bounded, buffered parsing. Application code is responsible for storing files persistently.
Multipart DTO#
#[derive(MultipartForm)]
struct UploadInput {
title: String,
#[form_file]
attachment: FormFile,
}
#[derive(serde::Serialize)]
struct UploadInfo { title: String, bytes: usize }MultipartForm and FormFile come through lily_http_api. Add the following action to the controller:
#[post("/upload")]
async fn upload(&self, MultipartForm(input): MultipartForm<UploadInput>)
-> Result<UploadInfo, HttpApiError>
{
Ok(UploadInfo { title: input.title, bytes: input.attachment.len() })
}An example request with the /files base path:
curl -i http://127.0.0.1:8080/files/upload \
-F 'title=Profil görseli' \
-F 'attachment=@./avatar.png'The response returns the title and byte count; it does not save the file to disk or an object store. Download the complete controller example. This combined example includes a static-file mount, so create a public directory before startup and add futures = "0.3".
Field rules#
The multipart derive supports String, Option<String>, and Vec<String> for text; and FormFile, Option<FormFile>, and Vec<FormFile> for files. File fields carry #[form_file]. Unknown fields, duplicate scalar fields, and missing required fields are rejected. Sending a text field as a file or a file field as text is not accepted. Express required, optional, and repeated fields in your DTO.
Upload limits#
Defaults are 8 MiB per part, 128 parts, and 16 KiB of metadata. The overall request body limit is enforced separately. When tightening limits with HttpTransportConfig, ensure the part limit does not exceed the body limit.
A filename or client-reported MIME type is not a trusted storage path or proof of file type. Your application must choose the storage name and allowed-content policy.
Large requests#
Multipart is buffered on this path. Consider BodyStream::next_chunk for processing a large byte stream incrementally, while preserving body ownership rules. Uploading and serving files are operations in opposite directions.
Sources for this page v0.1.0
This guide is based on the reviewed framework commit.