Set Up Mongoose With ExpressJS

Search for a command to run...

No comments yet. Be the first to comment.
In this series, we will build a basic social application using ExpressJS, MongoDB.
In this article, I’m going to demonstrate how to build a user registration and authentication system in ExpressJS. In the previous article, we set up a MongoDB connection using Mongoose. Here we’ll be using that connection to save user data and use i...
I started working on an open-source project about a year ago to build an embeddable alternative to Redis in Go. That’s when I started building the EchoVault project. Since then, the project has gained some interest and even a few contributors. This a...

AWS Cognito user pools allow you to manage your app's within the AWS ecosystem. It provides all the basic features you'd expect from an auth system. When I'm building an application on AWS infrastructure, I prefer using Cognito user pools due to its ...

AWS offers an easy way to work with web sockets through the WebSockets API in API Gateway. This article is going to be a short walkthrough on how to get started with WebSocket APIs. Setup This is article is based on a serverless framework project. Yo...

I've previously written an article about basic username/password authentication with AWS Cognito. This article will cover registration and authentication using Google. Cognito offers this functionality built into the hosted-ui. However, if you find ...

Recently, I posted an article about pre signup triggers for AWS Cognito user pools. The article went over setting up pre signup validation using a lambda function. In this article, I'm going to demonstrate how to achieve the same goal, but using the ...

In the previous article, I demonstrated how to set up Nunjucks template engine in your express project. I decided to make this a full-fledged web app development series of articles by progressively building the example application. In this article, we are going to connect the app to a MongoDB database using Mongoose.
Mongoose is an ODM (Object Document Mapper) that allows interaction with MongoDB databases using JavaScript objects.
It provides extra functionality (such as static methods on the schema) that allows us to enhance database interactions and write cleaner code.
At the time of writing this article, the latest stable version of Mongoose is v5.11.8. This will most likely be different at the time of reading although most of the information here should still be relevant.
Makes sure you have a MongoDB server installed and running on your system before following along. If not, you can sign up for a free cluster at MongoDB Atlas and connect to that instead.
Install Mongoose and dotenv using the following command:
npm install mongoose dotenv
Dotenv allows us to load environment variables into our application. We are going to place the MongoDB URI in an environment variable file instead of hard-coding it.
Doing this allows us to connect to different MongoDB instances in different environments by only changing this URI in the environment variable without changing the code itself.
Create a file called .env in the root of your project. The contents of the files should be as follows:
PORT=8000
MONGO_URI=mongodb://localhost:27017/app
We’ve defined the port here along with the MongoDB URI. make sure to change the values according to your setup.
Now go back to your index.js file (or the file in which your app instance is initialised) and add the following line at the beginning of the file:
if (process.env.ENV === 'dev') require('dotenv').config()
This loads the .env file in our project if we’re in the development environment. We can access each environment variable using process.env.<variable\_name>.
The dotenv package will look for the .env file in our project when the config method is invoked.
Placing this at the top of the entry point file ensures the environment variables are available to the entire application when we decide to go with a modular approach with our route organisation.
Now import mongoose:
const mongoose = require('mongoose')
Create a mongoose connection by inserting the following code before the route definitions:
const connection = mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
/* Display message in the console if the connection is successful. */
mongoose.connection.once('open', () => {
console.log('connected!')
})
Our mongoose connection has been established. The next step is to define our models. Models are object representations of the documents that will reside in our database.
Models in mongoose require a schema. A schema specifies the structure of the document.
If you’re familiar with NoSQL databases, particularly MongoDB, you might be aware that one of the benefits is that the schema is dynamic. Meaning you can add new fields to a document on the fly upon creation/update.
This may be a good idea depending on your use case but mongoose requires schemas in order to define the shape of the documents in the collection. This ensures we have consistency in a collection and a reference point for what properties are contained in each document.
Let’s begin setting up our models by creating a folder in the root of our project named ‘model’. Next, create a file inside this folder called ‘User.js’. It’s a good idea to separate models into their own files.
Inside User.js, add the following code:
const { Schema, model } = require('mongoose')
var userSchema = new Schema({
name: {
type: Schema.Types.String,
required: [true, 'You must provide a name']
},
email: {
type: Schema.Types.String,
required: [true, 'Email address is required']
},
username: {
type: Schema.Types.String,
required: [true, 'Username is required']
},
password: {
type: Schema.Types.String,
required: [true, 'You must provide a password']
}
})
const User = model('User', userSchema)
module.exports = User
Let’s walk through the contents of this file:
Now create an index file within the models directory. This file will import all of the models from its sibling files and export them in an object. We’re doing this to reduce the number of require statements in other files when importing models.
You can certainly import models directly from their respective files, but this is definitely a cleaner way of doing it.
The contents of this index.js file should look like this for now:
const User = require('./User')
module.exports = {
User
}
It’s time to test if this works. We’re going to insert a user into the collection if the collection is empty and retrieve the users in the collection otherwise.
In the app entry file, import the User model from the models index file as follows:
// Import models
const { User } = require('./models')
Update the home route to the following:
app.get('/', async (req, res) => {
const users = await User.find({})
if (users.length) {
/* Log users if users exists. */
console.log(users)
} else {
/* If no users exist, save new user and log saved user on the console. */
let newUser = new User({
name: 'Kelvin Mwinuka',
email: 'email@kelvinmwinuka.com',
username: 'kelvin',
password: 'password'
})
let savedUser = await newUser.save()
console.log(savedUser)
}
res.render('home.html')
})
Navigate to this route in the browser and you should notice that for the first time, a single object is printed to the console:
{
_id: 5fdab492561efb3e9a2c56c7,
name: 'Kelvin Mwinuka',
email: 'email@kelvinmwinuka.com',
username: 'kelvin',
password: 'password',
__v: 0
}
When you refresh the page, the results should now be as follows:
[
{
_id: 5fdab492561efb3e9a2c56c7,
name: 'Kelvin Mwinuka',
email: 'email@kelvinmwinuka.com',
username: 'kelvin',
password: 'password',
__v: 0
}
]
Notice this is an array of current documents and no new user is created/saved.
That’s it. We’ve successfully set up mongoose and we’re ready to start persisting data in our MongoDB database!
In this article, we’ve gone over connecting our express application to a MongoDB database, creating mongoose models and using those models to save data into our database.
In the next article, I will be going over user registration and authentication using Passport JS.
You can track the progress of this project on Github.