Skip to content

File Upload

You need to accept file uploads via multipart/form-data, enforce size limits, and access file content (name, filename, body buffer) from within your execute handler.

ergo’s body() middleware handles multipart parsing automatically. When the request Content-Type is multipart/form-data, acc.body.parsed contains an array of part objects — one per form field or file.

import {compose, body} from '@centralping/ergo';
const pipeline = compose(
body(),
async (req, res, acc) => {
const [file] = acc.body.parsed;
await saveFile(file.filename, file.body);
return {
response: {
statusCode: 201,
body: {filename: file.filename, size: file.body.length},
},
};
},
);
import {compose, body} from '@centralping/ergo';
const pipeline = compose(
body({limit: 10 * 1024 * 1024}),
async (req, res, acc) => {
const files = acc.body.parsed.filter((part) => part.filename);
const results = await Promise.all(
files.map((file) => saveFile(file.filename, file.body)),
);
return {
response: {
statusCode: 201,
body: {uploaded: results.length},
},
};
},
);
import {compose, body} from '@centralping/ergo';
const pipeline = compose(
body(),
async (req, res, acc) => {
const parts = acc.body.parsed;
const description = parts.find((p) => p.name === 'description');
const file = parts.find((p) => p.filename);
return {
response: {
statusCode: 201,
body: {
description: description?.body.toString(),
filename: file?.filename,
},
},
};
},
);

When the body middleware parses a multipart/form-data request, acc.body.parsed is an array of part objects:

Property Type Description
headers object RFC 7578 §4.8 headers (content-disposition, content-type, content-transfer-encoding)
name string The form field name from Content-Disposition
filename string | undefined The original filename (present only for file fields)
body Buffer The raw binary content of the part

File fields have a filename property; regular form fields do not. Use this distinction to separate files from text fields in the parts array.

Option Default Description
limit 1048576 (1 MiB) Maximum total body size in bytes (compressed)
decompressedLimit min(10 × limit, 10 MiB) Maximum decompressed body size (bomb protection)

The limit applies to the entire multipart body — all parts combined, not per-part. For endpoints accepting large file uploads, increase the limit explicitly:

body({limit: 20 * 1024 * 1024}); // 20 MiB

The body middleware accepts multipart/form-data by default (included in the default types array). No additional configuration is needed to enable multipart parsing — it works out of the box alongside JSON and form-urlencoded bodies.

The multipart parser enforces a maximum of 100 parts per request by default, preventing abuse from requests with thousands of empty parts. This limit is internal to the parser and does not require configuration.