Skip to content

Mongoose Example

Users REST API with MongoDB

In this example, we will modify the Users REST API example to use the MongoDB database. Same queries will be send form the Postman to server side and same endpoints will be used in server side. We only modify codes inside the endpoints to communicate with MongoDB.

We will separate database connection and database model to different files under db and models directories.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.
├── index.js
├── db
   └── mongodb.js
├── controllers
   └── usersController.js
├── middleware
   └── logger.js
├── models
   └── User.js
├── node_modules
├── package.json
└── routes
    └── users.js

Project

Take a copy of the previous version of Users REST API and make below modification. This way you will have both of the versions.

Mongoose

MongoDB can be accessed directly using Node.js's Mongo driver library, but it's a bit hard. The Mongoose module is available for this purpose. Through Mongoose, JavaScript objects can be saved directly as Mongo documents.

We are going to use the Mongoose ODM to access our users data. Mongoose will act as a front end to MongoDB. This ODM (Object Data Model) and database combination is extremely popular in the Node community. Document storage and queries looks very much like JSON and it is familiar to JavaScript developers.

Install Mongoose module to your project:

1
npm i mongoose

Dotenv

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. You can use this module to store your host, port and passwords to environment-specific variables.

Install dotenv module to your project:

1
npm i dotenv

Create a .env file to root of your project and remember add used port and MongoDB connection string into it.

.env
1
2
PORT = 3000
MONGODB = "mongodb+srv://pasi:PASSWD@democluster.brlob.mongodb.net/test"

Remember use .gitignore and add .env and node_modules into it, so those will not be published to Git clouds.

.gitignore
1
2
.env
node_modules

Connection to database

Create a new db folder and a new mongodb.js file inside it. As for the mongodb.js, the database connection is separated and later imported in to index.js. The parameters are used for supressing deprecation warnings when initiating the connection.

db/mongodb.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const mongoose = require('mongoose')

// fix Mongoose strictQuery deprecation Warning
mongoose.set('strictQuery', false) 

const connectMongoDB = async (url) => {
  return mongoose.connect(url, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
}

module.exports = connectMongoDB

And require it in index.js.

index.js
1
const connectMongoDB = require('./db/mongodb')

We will made a connection to MongoDB a little bit differently compared to earier given course materials. We will first check if the connection to MongoDB can be established correctly. If this happens we will start the actual server. Here we can use async/await keywords which are working nicely in this situation.

index.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// connect mongodb and start server
const start = async () => {
  try {
    await connectMongoDB(process.env.MONGODB)
    app.listen(
      process.env.PORT, 
      () => console.log(`Server listening on port ${process.env.PORT}`)
    )
  } catch (error) {
    console.log(error)
  }
}

// start connection to mongodb and start server
start()

Save your files and test that connection to MongoDB is working.

Users model

Create a new models folder and User.js file into it. We will use this model in usersController.js.

User.js
1
2
3
4
5
6
7
8
9
const mongoose = require('mongoose')

const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  phone: String,
})

const User = mongoose.model('User', userSchema)

Modify controllers to use MongoDB

Remove/comment previously used JSON based users data and require User model.

usersController.js
1
2
3
4
5
6
// use sample users data
//let { users } = require('../data')

// require User moodel
const User = require('../models/User')
...

createUser

Modify createUser function to communicate with MongoDB. We are getting data from the client in the body of the POST request and pass it on to the models create() function, which is just a thin wrapper for the save() function what we have used previously in the MongoDB examples.

createUser
1
2
3
4
5
6
7
8
9
const createUser = async (req, res) => {
  try {
    const user = await User.create(req.body)
    res.status(201).json({ success: true, data: user })
  } catch (error) {
    console.log(error)
    res.status(400).json({ success: false, msg: 'No user value provided!' })
  }
}

Use Postman and create a one user document.

getUsers

Modify getUsers function to communicate with MongoDB. We are returning the status code 200 OK and the data or 500 internal server error in case of an error.

getUsers
1
2
3
4
5
6
7
8
const getUsers = async (req, res) => {
  try {
    const users = await User.find({})
    res.status(200).json({ success:true, data:users })
  } catch (error) {
    res.status(500).json({ success:false, msg: error })
  }
}

Use Postman to get all the user documents.

getUser

Modify getUser function to communicate with MongoDB. User's id is sent from client to server with request parameters.

getUser
1
2
3
4
5
6
const getUser = async (req, res) => {
  const { id } = req.params
  const user = await User.findById(id)
  if (user) res.status(200).json({ success:true, data:user })
  else res.status(500).json({ success:false, error:"User not found!" })
}

Use Postman to get one user document.

updateUser

Modify updateUser function to communicate with MongoDB.

updateuser
1
2
3
4
5
6
7
const updateUser = async (req, res) => {
  const { id } = req.params
  const { name, email, phone } = req.query
  let user = await User.findByIdAndUpdate(id, req.query, {new: true})
  if (user) res.status(200).json({ success:true, data:user })
  else res.status(500).json({success:false,error:`No user found with id ${id}`})
}

Use Postman and update on user document.

Read More

Goals of this topic

Understand

  • Use Mongoose with Node/Express application.