The Five Lines of Code That Changed Everything

After three grueling days of debugging, scouring forums, using Copilot/GPT-4o/Llama 3 and piecing together snippets of documentation, I had an epiphany. It was a moment of clarity that came from the most unexpected source: five simple lines of code.

export const config = {
    api: {
        bodyParser: false,
    },
};

These lines might not look like much, but they represent a turning point in my journey with Next.js API routes. Let me take you back to where it all began.

The Struggle

As a developer, I'm no stranger to the challenges that come with learning new technologies. My latest project involved creating a custom API route in Next.js with TypeScript, which required handling incoming requests in a specific manner. I needed to parse the request body manually, bypassing the default bodyParser that Next.js provides.

The documentation on this was sparse, and most examples I found online didn't address my use case. I used multer / multiparty etc but missed the above 5 lines, causing it to crash every time. I was stuck in an endless loop of trial and error, with each iteration leading to more frustration. I also had a couple of friends take a look at my code and give up.

The Breakthrough

On the third day, as I was about to call it quits, I stumbled upon a piece of documentation that mentioned disabling the bodyParser for API routes. It was a feature designed for scenarios where the developer needs full control over the request processing, such as verifying webhook requests with their raw body.

The code snippet above is the key to this functionality. By setting bodyParser to false, it tells Next.js not to parse the incoming request body automatically. This allows you to handle the body as a raw stream or with a custom parser, which is exactly what I needed for my project.

The Resolution

Implementing these five lines of code was the last piece of a puzzle. Suddenly, everything clicked into place. My API route worked flawlessly, and I could process the request body exactly as required.

This experience taught me an invaluable lesson: sometimes, the solution lies in the details that are easily overlooked. It's a reminder that perseverance pays off, and that even the smallest lines of code can have a significant impact on your work.

Here is the final code that worked:

import {NextApiRequest, NextApiResponse} from "next";
import {IncomingForm} from "formidable";

export const config = {
    api: {
        bodyParser: false,
    },
};

export default async function handler(req: NextApiRequest, res: NextApiResponse): Promise<void> {
    if (req.method !== 'POST') {
        // Return error
        res.status(405).json("Method not allowed for File Upload");
    }
    // Do your authentication magic here first
    // Get the headers using req.headers.<header name> ....
    try {
        const data: { files: any } = await new Promise((resolve, reject) => {
            const form = new IncomingForm();
            form.parse(req, (err: any, fields: any, files: any) => {
                if (err) reject({err});
                resolve({files});
            });
        });

        Object.keys(data.files).forEach((key) => {
            // Here you can handle the file, e.g. save it to disk, upload to cloud storage, etc.
            console.log(`Received file ${key}:`, data.files[key]);
        });

        res.status(200).json("Successfully received file(s)");
    } catch (error: any) {
        res.status(500).json(error.message);
    }
};

Continue the Discussion

If you are implementing file uploads and want help with API design, validation, storage patterns, and security hardening, book a CTO consultation.

You can also connect with me on LinkedIn to discuss your use case.