How to Connect to MongoDB in NextJS Simple way

How to Connect to MongoDB in NextJS Simple way

How to Connect to MongoDB in NextJS Simple Way

Learn how to connect to MongoDB in your NextJS application in a simple way using Mongoose and Typescript.

Introduction

Connecting to MongoDB in a NextJS app can seem tricky, but it's actually pretty simple. In this guide, I'll show you how to set up a connection using Mongoose and TypeScript. We will ensure that our connection is efficient by using the Singleton pattern.

Why Singleton Pattern?

Every API route in NextJS is a separate serverless function. This means that each time an API endpoint is called, a new instance is created. To avoid creating multiple connections per instance to the database, we use the Singleton pattern. This pattern ensures that only one instance of the database connection is created and reused.

Setting Up the MongoDB Connector

First, let's create a MongoDB connector class. This class will handle the connection logic and ensure we only create one connection instance.

import mongoose, { Mongoose, ConnectOptions } from "mongoose";

class MongoDBConnector {
  constructor() {
    if (!process.env.MONGODB_URI) {
      throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
    }
  }

  private async connectMongoDB(
    mongoURI: string,
    options: ConnectOptions
  ): Promise<Mongoose> {
    const connectionOptions = {
      dbName: "main",
      ...options,
    };

    const mongoDBURI = mongoURI ?? "";
    const mongoHost = new URL(mongoDBURI).host;

    mongoose.set("strictQuery", true);

    try {
      const connection = await mongoose.connect(mongoDBURI, connectionOptions);
      console.log(
        `\x1b[32m`,
        `Connected to MongoDB at ${mongoHost}`,
        `\x1b[0m`
      );
      return connection;
    } catch (err) {
      console.log(
        `\x1b[31m`,
        "Error connecting to MongoDB => ",
        err,
        `\x1b[0m`
      );
      throw err;
    }
  }

  private async initializeMongoDBConnection() {
    try {
      global.mongooseCon = await this.connectMongoDB(
        process.env.MONGODB_URI as string,
        {}
      );
    } catch (error) {
      console.log("Error MongoDB Connection", error);
    }
  }

  static getInstance = async () => {
    if (global.mongooseCon) {
      return global.mongooseCon;
    }
    await (new MongoDBConnector()).initializeMongoDBConnection();
    return global.mongooseCon;
  }
}

export const MongoDBConnectionClient = MongoDBConnector;

Using the MongoDB Connector in API Routes

Now that we have our connector, let’s see how we can use it in our NextJS API routes to perform CRUD operations. Each API route in NextJS is a separate function, so we need to ensure we connect to the database every time a request is made. Here’s an example:

import { MongoDBConnectionClient } from './path/to/mongodb-connector';
import { PostModel } from './path/to/post-model';
import { validatePostPOST } from './path/to/validation';
import slugify from 'slugify';

const PostRequest = WithAuth(async function (request: Request) {
    try {
        const body = await request.json();
        await validatePostPOST(body);
        Object.assign(body, {
            slug: slugify(body.title, { lower: true })
        });
        await MongoDBConnectionClient.getInstance();
        const newItem = new PostModel(body);
        await newItem.save();
        return Response.json({ status: "success" });
    } catch (error) {
        if (error instanceof Error) {
            console.log("Error while processing the request", error.message);
            return Response.json({ status: "failed", message: error.message });
        }
    }
});

Detailed Explanation

MongoDBConnector Class

  1. Constructor: Checks if the MONGODB_URI environment variable is set.
  2. connectMongoDB Method: Connects to the MongoDB database using the provided URI and options. Logs the connection status.
  3. initializeMongoDBConnection Method: Initializes the MongoDB connection and stores it in a global variable.
  4. getInstance Method: Checks if a connection already exists. If not, initializes a new connection.

Using the Connector in API Routes

  • WithAuth Middleware: Ensures the request is authenticated.
  • PostRequest Handler: Handles the POST request to create a new post.
  • Parses the request body.
  • Validates the data.
  • Adds a slug to the post title.
  • Connects to MongoDB using the Singleton instance.
  • Saves the new post to the database.
  • Returns a success response.

Conclusion

By using the Singleton pattern and Mongoose, we can efficiently manage our MongoDB connections in a NextJS application. This approach ensures that we only create one connection instance, avoiding unnecessary overhead. I hope this guide helps you set up your MongoDB connection in your NextJS projects easily!

Happy coding!


Feel free to copy and modify the code snippets according to your needs.

  • #NextJS
  • #Mongoose
  • #MongoDB
  • #Singletone