I'm building a form backend like Formspree on NextJS, so I need to be able to receive all form POSTs at the same endpoint, without being able to control what the forms enctype
is set as. I need to be able to read the req.body no matter the enctype, and if it's a multipart form then I need to get the files that are attached to the request too.
Currently I do this by running the request though both multer and bodyparser everytime like so:
// Middleware helper
const runMiddleware = (req, res, fn) => new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
handler.post(async (req, res) => {
const fileUploadAllowed = // business logic
if (fileUploadAllowed) {
// Parse req.files
await runMiddleware(
req,
res,
multer({
limits: { fileSize: MAX_FILE_SIZE },
storage: multerS3({
s3,
bucket: process.env.FILE_SERVER_BUCKET,
acl: 'public-read',
key(_, file, cb) {
cb(null, `${user._id}/${form._id}/${submissionId}/${file.originalname}`);
},
}),
}).array('_file', 5),
);
}
// Parse the req.body
await runMiddleware(
req,
res,
bodyParser.urlencoded({ extended: true }),
);
await runMiddleware(
req,
res,
bodyParser.json(),
);
// Access here
console.log(req.files, req.body);
});
This setup works if the forms enctype is multipart/form-data
or application/x-www-form-urlencoded
, but the problem is if the fileUploadAllowed
is false then the req never runs through Multer, and if the form is multipart then the body will be empty too and the whole POST is rejected. I can't just run it through Multer no matter what because the files are automatically uploaded to my S3 bucket.
What is the best way to handle this setup?