DEV Community

loading...

Adding MongoDB (Mongoose) to Next.js APIs

raphaelchaula profile image Raphael Chaula ・2 min read

After you have created a Next.js app, install mongoose yarn add mongoose then create next.config.js at the root directory of your app if it doesn't exist and in it add your MongoDB connection url string.

next.config.js

module.exports = {
    env: {
        mongodburl: "Your MongoDB connection String",
    }
};
Enter fullscreen mode Exit fullscreen mode

Then create a MongoDB connect middleware that will be called to create a new connection to DB or reuse the existing one whenever we do an operation to DB, in my case I added middleware folder in the root directory of the app and added it there.

middleware/mongodb.js

import mongoose from 'mongoose';

const connectDB = handler => async (req, res) => {
  if (mongoose.connections[0].readyState) {
    // Use current db connection
    return handler(req, res);
  }
  // Use new db connection
  await mongoose.connect(process.env.mongodburl, {
    useUnifiedTopology: true,
    useFindAndModify: false,
    useCreateIndex: true,
    useNewUrlParser: true
  });
  return handler(req, res);
};

export default connectDB;
Enter fullscreen mode Exit fullscreen mode

Then create your models, in my case I added models folder in root directory of the app and created a User model in it.

models/user.js

import mongoose from 'mongoose';
var Schema = mongoose.Schema;

var user = new Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  since: {
    type: Date,
    default: Date.now
  }
});

mongoose.models = {};

var User = mongoose.model('User', user);

export default User;
Enter fullscreen mode Exit fullscreen mode

Then lets create an api for user and add create a new user functionality in it in the pages/api/user directory.

pages/api/user.js

import connectDB from '../../middleware/mongodb';
import bcrypt from '../../middleware/bcrypt';
import User from '../../models/user';

const handler = async (req, res) => {
  if (req.method === 'POST') {
    // Check if name, email or password is provided
    const { name, email, password } = req.body;
    if (name && email && password) {
        try {
          // Hash password to store it in DB
          var passwordhash = await bcrypt.sign(password);
          var user = new User({
            name,
            email,
            password: passwordhash,
          });
          // Create new user
          var usercreated = await user.save();
          return res.status(200).send(usercreated);
        } catch (error) {
          return res.status(500).send(error.message);
        }
      } else {
        res.status(422).send('data_incomplete');
      }
  } else {
    res.status(422).send('req_method_not_supported');
  }
};

export default connectDB(handler);
Enter fullscreen mode Exit fullscreen mode

We are done here, just make a post request to http://localhost:3000/api/user in the request body include: name email and password you will get a response either user object if user is created successfully or an error message if something went wrong.

Happy Hacking!

Discussion (13)

pic
Editor guide
Collapse
nasiruddinsaiyed profile image
Nasiruddin Saiyed • Edited

Well explained, +1, but it will not work if we are exporting next project into static site using next export. [nextjs.org/docs/api-routes/introdu...]

dev-to-uploads.s3.amazonaws.com/i/...

Collapse
raphaelchaula profile image
Raphael Chaula Author

Yes, API routes only work server side (Lambdas) in Next.js.

Collapse
bias profile image
Tobias Nickel

nice, thanks, never used next, but wanted to know how APIs are done with it. However I looked some more into the official docunentation.

It loojs very straight forward. 👍

Collapse
raphaelchaula profile image
Raphael Chaula Author

You're welcome.

Collapse
regisnut profile image
Regisnut

Hi, can you precise if I host the website on vercel, if mongodb will be on vercel too? or do I need to host it on heroku as an example?
thanks

Collapse
raphaelchaula profile image
Raphael Chaula Author

You can host the website on vercel, it will work just fine, I used MongoDB Atlas, so you can host MongoDB anywhere.

Here is what you should not do;
Don't export the Next.js app, it has to be server side.

Collapse
regisnut profile image
Regisnut

Ouah, nice to hear ! I will use MongoDB atlas too with mongoose.
But I'm still a noob, I don't know what is export a Next.js App?

Thread Thread
raphaelchaula profile image
Raphael Chaula Author

Export is when you want to build a Next.js app into static HTML file.
You can read more about it here nextjs.org/docs/advanced-features/...

Collapse
fedecingerle profile image
Federico Cingerle

Hi! do you have a github repo with this explanation? If you have it, could you share it?

Collapse
raphaelchaula profile image
Raphael Chaula Author • Edited

I don't have any repo specifically to that article but here is a project similar, you can check it out, github.com/raphaelchaula/joinshift... , it is a Next.js project with Mongoose and MongoDB.

Collapse
fedecingerle profile image
Federico Cingerle

Thanks very much!!!!

Collapse
megens profile image
Robert Megens

Thanks very much. NextJS seemingly rebuilds my User model at each page call, so this line saved me a persistent overwrite warning error:

mongoose.models = {};

Collapse
raphaelchaula profile image
Raphael Chaula Author

You are welcome.