Read req.body whether multipart/form-data or application/x-www-form-urlencoded entype form?

663 Views Asked by At

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?

0

There are 0 best solutions below