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(
{fn: body(), setPath: "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(
{fn: body({ limit: 10 * 1024 * 1024 }), setPath: "body"},
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(
{fn: body(), setPath: "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:

PropertyTypeDescription
headersobjectRFC 7578 §4.8 headers (content-disposition, content-type, content-transfer-encoding)
namestringThe form field name from Content-Disposition
filenamestring | undefinedThe original filename (present only for file fields)
bodyBufferThe 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.

OptionDefaultDescription
limit1048576 (1 MiB)Maximum total body size in bytes (compressed)
decompressedLimitmin(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.