DEV Community

Cover image for The Complete Guide to Becoming a Web Developer: Part 9
Ahmed Radwan for Nerd Level Tech

Posted on • Originally published at nerdleveltech.com

The Complete Guide to Becoming a Web Developer: Part 9

Welcome, tech enthusiasts and web developers, to another part of the series "Becoming a web developer". This article will dive into an exciting journey exploring the world of MongoDB Cloud Atlas, Node.js, and Mongoose.

If you are new here please start with part 1 of this series here.

Introduction

In this article, we will be diving deep into the practical aspects of deploying web applications, specifically focusing on MongoDB Cloud Atlas, a powerful, fully-managed cloud database developed by the same people that build MongoDB. MongoDB Cloud Atlas takes the pain out of database management, freeing you up to focus on what matters most, your application.

To complement MongoDB and Node.js, we will also delve into Mongoose. Mongoose is an elegant MongoDB object modeling for Node.js. It provides a straightforward, schema-based solution to model your application data, complete with built-in type casting, validation, query building, and business logic hooks.

Throughout this guide, we will be building a simple Content Management System (CMS) as an example to help you understand the practical application of these technologies. We will walk you through the process step-by-step, providing well-documented code examples that are commonly used in the industry and will help you when you reach the documentation stage. We will also share best practices for structuring databases and designing schemas, and help you troubleshoot common issues that might come up during the deployment process.

So, buckle up and get ready to dive into the exciting world of MongoDB Cloud Atlas, Node.js, and Mongoose. By the end of this guide, you will have a solid understanding of these technologies and will be well-equipped to deploy your own web applications. Let's get started!

Setting Up the Environment

Before we dive into the depths of application development, we need to ensure that our environment is properly set up. This involves installing the necessary software and tools, setting up MongoDB Cloud Atlas, and preparing our Node.js environment. Don't worry if this sounds overwhelming; we'll guide you through each step of the process.

Installing Necessary Software and Tools

First things first, we need to install Node.js and npm (Node Package Manager). Node.js is the runtime environment we'll use to run our server-side JavaScript code, and npm is a package manager for Node.js that will help us install other tools and libraries we'll need.

To install Node.js and npm, head over to the official Node.js website and download the installer for your operating system. Run the installer and follow the prompts. To verify that the installation was successful, open a terminal or command prompt and run the following commands:

node -v
npm -v

These commands should display the versions of Node.js and npm you installed.

Setting Up MongoDB Cloud Atlas

Next, we'll set up MongoDB Cloud Atlas. MongoDB Cloud Atlas is a fully-managed cloud database service that automates time-consuming administration tasks such as hardware provisioning, database setup, patching, and backups, freeing you to focus on your applications.

To get started with MongoDB Cloud Atlas, follow these steps:

  1. Go to the MongoDB Cloud Atlas website and sign up for a free account.
  2. Once you're logged in, create a new project by clicking on "New Project". Give your project a name and click "Next".
  3. Now, create a new cluster by clicking on "Build a Cluster". For this guide, you can use the free tier available.
  4. Choose a cloud provider and a region for your cluster. For the sake of this guide, any provider and region will do.
  5. Click "Create Cluster". It might take a few minutes for your cluster to be ready.

Once your cluster is ready, you'll need to set up a database user and allow network access. To do this:

  1. Click on the "Database Access" under the "Security" section in the left-hand menu.
  2. Click "Add New Database User". Choose a username and a password, and give this user "Read and write to any database" privileges.
  3. Click "Add User".
  4. Now, go to "Network Access" under the "Security" section.
  5. Click "Add IP Address". For this guide, you can allow access from anywhere by entering "0.0.0.0/0", but in a real-world scenario, you would want to restrict this to the IP addresses that need access to your database.
  6. Click "Confirm".

Finally, you'll need to get the connection string to use in your application:

  1. Go to your cluster's overview by clicking on "Clusters" in the left-hand menu.
  2. Click "Connect".
  3. Choose "Connect your application".
  4. Copy the connection string, but remember to replace <password> with the password of the database user you created.

Setting Up Node.js Environment

With Node.js installed and MongoDB Cloud Atlas set up, we're ready to create our Node.js environment. First, we'll create a new directory for our project. Open a terminal or command prompt, navigate to where you want your project to be, and run:

mkdir my-cms
cd my-cms

Next, we'll initialize a new Node.js project in this directory:

npm init -y

This command creates a new package.json file in your directory with default values.

Finally, we'll install Express, a popular web application framework for Node.js, and Mongoose, which we'll use to interact with our MongoDB database:

npm install express mongoose

And that's it! You now have a Node.js environment ready for development, MongoDB Cloud Atlas set up, and all the necessary tools installed. In the next sections, we'll start building our CMS system and dive into Mongoose and schema design. Let's get coding!

Building a CMS System: An Example

Now that we have our environment set up, it's time to roll up our sleeves and start coding. In this section, we'll be building a Content Management System (CMS) as an example to demonstrate the practical application of MongoDB Cloud Atlas, Node.js, and Mongoose. A CMS is a software that allows users to create, manage, and modify content on a website without the need for specialized technical knowledge.

Overview of the CMS System

Our CMS will be a simple yet functional system that allows users to create, read, update, and delete (CRUD) articles. Each article will have a title, content, and an author. Users will be able to view all articles, view a single article, create a new article, update an existing article, and delete an article.

This CMS will serve as a practical example to understand how to structure a Node.js application, how to design a database schema using Mongoose, and how to perform CRUD operations using MongoDB Cloud Atlas.

Designing the Application Structure

When building a Node.js application, it's important to structure your project in a way that keeps it organized and scalable. Here's how we'll structure our CMS:

/my-cms
  /node_modules
  /models
    - Article.js
  /routes
    - articles.js
  - package.json
  - server.js

Here's what each file and directory does:

  • node_modules: This directory is created by npm and holds all the packages we've installed.
  • models/Article.js: This is where we'll define our Mongoose model for the articles.
  • routes/articles.js: This is where we'll define our Express routes for handling the CRUD operations for the articles.
  • package.json: This file was created by npm init and holds metadata about our project and the list of packages our project depends on.
  • server.js: This is the entry point of our application. It's where we'll set up Express and Mongoose, and start our server.

In the next sections, we'll start implementing our CMS system. We'll begin by defining our Mongoose schema and model in models/Article.js, then we'll move on to implementing the Express routes in routes/articles.js. Finally, we'll set up our server in server.js.

Remember, the key to learning is practice. Don't hesitate to experiment and try different things. If you encounter any issues or have any questions, don't worry. We'll cover common issues and troubleshooting later in this guide. Now, let's start building our CMS!

Mongoose and Schema Design

As we embark on the journey of building our CMS system, one of the key aspects we need to understand is schema design. In MongoDB, a schema is the organization of data as a blueprint of how the database is constructed. While MongoDB is schema-less, SQL databases require a predefined schema. Mongoose brings the power of schema to MongoDB, making data modeling easier.

Introduction to Mongoose

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It provides a straightforward, schema-based solution to model your application data and includes built-in type casting, validation, query building, and business logic hooks.

In essence, Mongoose provides a layer of features on top of MongoDB's driver to make it easier and more intuitive to work with our data. It allows us to define objects with a strongly-typed schema that is mapped to a MongoDB document.

Designing Schemas for the CMS System

Now, let's design the schema for our CMS system. As mentioned earlier, each article in our CMS will have a title, content, and an author. Here's how we can define this schema using Mongoose:

const mongoose = require('mongoose');

const ArticleSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
    trim: true,
    maxlength: 100
  },
  content: {
    type: String,
    required: true
  },
  author: {
    type: String,
    required: true,
    trim: true,
    maxlength: 50
  }
});

module.exports = mongoose.model('Article', ArticleSchema);

In this code, we first import Mongoose, then we define a new schema using new mongoose.Schema(). For each field in our schema, we define the type of the data and any options. In this case, we've marked all fields as required, and we're trimming the title and author fields to remove any leading or trailing whitespace. We've also set a maximum length for the title and author fields. Lets implement a documentation example of the article schema we just implemented.

Article Model Documentation

Our CMS system revolves around the Article model. This model represents an article in our CMS, and it's used to interact with the articles collection in our MongoDB database.

Here's what each field represents:

  • title: The title of the article. It's a string that's required, trimmed to remove leading and trailing whitespace, and has a maximum length of 100 characters.
  • content: The content of the article. It's a string that's required.
  • author: The author of the article. It's a string that's required, trimmed to remove leading and trailing whitespace, and has a maximum length of 50 characters.

Finally, we create a model from our schema using mongoose.model() and export it. This model is what we'll use in our routes to interact with the articles in our MongoDB database.

Best Practices for Structuring Databases and Designing Schemas

When structuring databases and designing schemas, there are a few best practices you should keep in mind:

  • Keep your schemas simple: Try to keep your schemas as simple and intuitive as possible. This makes your data easier to work with.
  • Use the right data types: Mongoose supports many data types, including strings, numbers, dates, buffers, booleans, mixed, objectid, arrays, decimals, maps, and sets. Using the right data type for each field can help you ensure data integrity and can make your data easier to work with.
  • Validate your data: Mongoose allows you to define validation rules for your fields. This can help you ensure that the data stored in your database is valid and consistent.
  • Use indexes for faster queries: If you have fields that you'll query frequently, consider adding indexes to these fields. Indexes can make your queries faster.
  • Avoid large embedded arrays or documents: While MongoDB allows you to embed arrays or documents in your documents, large embedded arrays or documents can lead to performance issues. If you find yourself needing large embedded arrays or documents, consider splitting your data into separate collections.

Remember, these are just guidelines, and the best structure or schema for your database depends on your specific use case. In the next section, we'll start implementing our CMS system using the schema we've just designed. Let's get coding!

Implementing the CMS System

With our environment set up and our schema designed, it's time to start implementing our CMS system. In this section, we'll guide you through the process step-by-step, incorporating MongoDB Cloud Atlas and Mongoose into our application.

Step-by-step Guide to Building the CMS System

Setting Up the Server

First, let's set up our server. In your server.js file, add the following code:

const express = require('express');
const mongoose = require('mongoose');
const articles = require('./routes/articles');

const app = express();

app.use(express.json());
app.use('/articles', articles);

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));

In this code, we first import Express, Mongoose, and our articles routes. Then, we create an Express application and use the express.json() middleware to parse incoming requests with JSON payloads. We also set up our articles routes to be used with the /articles path.

Finally, we start our server on the port specified in the PORT environment variable, or port 5000 if PORT is not set.

Connecting to MongoDB Cloud Atlas

Next, we need to connect to our MongoDB Cloud Atlas database. Add the following code to your server.js file, before the line where you start your server:

mongoose
  .connect('your-connection-string', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  })
  .then(() => console.log('Connected to MongoDB Cloud Atlas'))
  .catch((err) => console.error('Could not connect to MongoDB Cloud Atlas', err));

Replace 'your-connection-string' with the connection string you got from MongoDB Cloud Atlas. This code connects to your MongoDB Cloud Atlas database using Mongoose. If the connection is successful, it logs a success message. If the connection fails, it logs an error message.

Implementing the Routes

Now, let's implement our routes. In your routes/articles.js file, add the following code:

const express = require('express');
const Article = require('../models/Article');

const router = express.Router();

// Get all articles
router.get('/', async (req, res) => {
  const articles = await Article.find();
  res.send(articles);
});

// Get one article
router.get('/:id', async (req, res) => {
  const article = await Article.findById(req.params.id);
  if (!article) return res.status(404).send('Article not found');
  res.send(article);
});

// Create a new article
router.post('/', async (req, res) => {
  let article = new Article({
    title: req.body.title,
    content: req.body.content,
    author: req.body.author,
  });
  article = await article.save();
  res.send(article);
});

// Update an existing article
router.put('/:id', async (req, res) => {
  const article = await Article.findByIdAndUpdate(
    req.params.id,
    {
      title: req.body.title,
      content: req.body.content,
      author: req.body.author,
    },
    { new: true }
  );
  if (!article) return res.status(404).send('Article not found');
  res.send(article);
});

// Delete an article
router.delete('/:id', async (req, res) => {
  const article = await Article.findByIdAndRemove(req.params.id);
  if (!article) return res.status(404).send('Article not found');
  res.send(article);
});

module.exports = router;

In this code, we first import Express, our Article model, and create a new router. Then, we define routes for each of our CRUD operations. Each route handler is an async function that uses Mongoose to interact with our MongoDB database. If an operation is successful, we send the result back to the client. If an operation fails, we send an error message back to the client.

And that's it! You now have a fully functional CMS system. You can use Postman or a similar tool to test your routes. In the next section, we'll prepare our application for deployment and deploy it using MongoDB Cloud Atlas. Let's keep going!

Deploying the Application

After all the hard work of building our CMS system, it's time for the most rewarding part - deploying our application. Deployment is the process of making our application available to users. In this section, we'll guide you through preparing your application for deployment and deploying it using MongoDB Cloud Atlas.

Preparing the Application for Deployment

Before we deploy our application, there are a few things we need to do to prepare it for the production environment:

1. Environment Variables: In our application, we've used a connection string to connect to our MongoDB Cloud Atlas database. This connection string contains sensitive information, like our database username and password. To protect this information, we should store it in environment variables instead of hardcoding it in our application. We can use the dotenv package to load environment variables from a .env file:

npm install dotenv

Then, create a .env file in the root of your project and add your environment variables:

DB_CONNECTION_STRING=your-connection-string

Now, you can load the environment variables in your server.js file:

require('dotenv').config();
mongoose.connect(process.env.DB_CONNECTION_STRING, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

Remember to add your .env file to your .gitignore file to prevent it from being committed to your Git repository.

2. Handling Errors: In a production environment, we want to handle errors gracefully and prevent them from crashing our application. We can use middleware in Express to catch and handle errors. This could be as simple as logging the error and sending a response with a 500 Internal Server Error status code.

3. Performance Optimization: In a production environment, performance is crucial. We've already discussed some performance optimization strategies, like adding pagination and caching. Another strategy is to compress our HTTP responses to reduce their size. We can use the compression middleware in Express to do this:

npm install compression

Then, use it in your server.js file:

const compression = require('compression');
app.use(compression());

Deploying the Application using MongoDB Cloud Atlas

With our application prepared for deployment, it's time to deploy it. There are many ways to deploy a Node.js application, but for this guide, we'll use Heroku, a popular cloud platform that supports Node.js applications.

1. Create a Heroku Account: If you don't already have a Heroku account, go to the Heroku website and sign up for a free account.

2. Install the Heroku CLI: The Heroku CLI is a tool that lets you create and manage your Heroku apps from the command line. Follow the official instructions to install the Heroku CLI.

3. Create a New Heroku App: In your terminal, navigate to your project directory and run the following command to create a new Heroku app:

heroku create

4. Push Your Code to Heroku: Heroku uses Git to deploy your app, so you'll need to commit any changes you've made:

git add .
git commit -m "Prepare for deployment"

Then, push your code to Heroku:

git push heroku master

5. Set Your Environment Variables: Remember those environment variables we set up earlier? We need to set them in Heroku as well. You can do this in the Heroku dashboard, or using the Heroku CLI:

heroku config:set DB_CONNECTION_STRING=your-connection-string

6. Open Your App: If everything went well, your app should now be deployed. You can open it in your web browser with the following command:

heroku open

Your CMS system is now live and accessible to the world. Congratulations on deploying your application! In the next section, we'll discuss some common issues you might encounter and how to troubleshoot them.

Troubleshooting and Common Issues

While building and deploying applications can be a rewarding process, it's not without its challenges. You're likely to encounter issues along the way, especially when dealing with complex systems like MongoDB Cloud Atlas and Mongoose. In this section, we'll discuss some common issues you might face and provide tips on how to troubleshoot them.

Common Issues During Deployment

Issue 1: Application Crashes on Startup

This is a common issue that can have many causes. It could be due to an error in your code, a missing environment variable, or a problem with your dependencies.

Troubleshooting: Check the logs of your application. On Heroku, you can do this by running heroku logs --tail in your terminal. The logs should give you a clue about what's causing the issue. If it's an error in your code, you might need to debug your code. If it's a missing environment variable, make sure you've set all your environment variables correctly. If it's a problem with your dependencies, try deleting your node_modules directory and package-lock.json file and running npm install again.

Issue 2: Application Works Locally But Not on Heroku

Sometimes, your application works perfectly on your local machine but fails when you deploy it to Heroku.

Troubleshooting: This could be due to differences between your local environment and the Heroku environment. Check your environment variables and make sure they're set correctly on Heroku. Also, make sure you're listening on the correct port. On Heroku, you should listen on process.env.PORT.

Common Issues While Using MongoDB Cloud Atlas and Mongoose

Issue 1: Connection Issues

One of the most common issues when using MongoDB Cloud Atlas and Mongoose is connection issues. You might see errors like "MongoNetworkError" or "MongooseServerSelectionError".

Troubleshooting: First, check your connection string and make sure it's correct. Remember to replace <password> with your actual password. Also, make sure your IP address is whitelisted in MongoDB Cloud Atlas. If you're still having issues, try connecting to your database using a MongoDB client like MongoDB Compass to see if the issue is with your application or with your database.

Issue 2: Validation Errors

Mongoose provides powerful validation features, but sometimes these can cause issues. For example, you might see a "ValidationError" when trying to save a document.

Troubleshooting: Check the error message to see which validation rule is failing. Then, check your schema and your data to make sure they match. Remember that Mongoose validation rules are case-sensitive and whitespace-sensitive.

Remember, troubleshooting is a skill that improves with practice. The more you work with these technologies, the better you'll get at diagnosing and fixing issues. Don't be discouraged if you run into problems - they're just opportunities to learn and improve.

Scale this Web App:

These stages you might want to consider when building this app on a bigger scale :

  1. Testing: It's important to thoroughly test your application to ensure it's working as expected. You can use tools like Postman to manually test your routes, or you can write automated tests using libraries like Jest or Mocha.
  2. Error Handling: While we've added some basic error handling to our route handlers, you might want to add more robust error handling to your application. This could include handling database errors, validation errors, and unexpected errors.
  3. Security: Before deploying your application, you should consider adding some security measures. This could include rate limiting to prevent abuse, CORS to restrict which domains can access your API, and data sanitization to prevent NoSQL injection attacks.
  4. Performance Optimization: There are many ways you can optimize the performance of your application. For example, you could add pagination to your "get all articles" route to limit the number of articles returned at once. You could also add caching to improve the performance of certain routes.
  5. Documentation: If other developers will be using your API, it's a good idea to provide documentation explaining how to use it. This could include a list of routes, the data they expect, and the data they return.
  6. Deployment: Once your application is tested, secure, and optimized, it's ready to be deployed. In the next section, we'll discuss how to prepare your application for deployment and how to deploy it using MongoDB Cloud Atlas.

Conclusion

And there we have it! We've journeyed through the process of deploying web applications and using MongoDB Cloud Atlas, from setting up our environment to deploying our CMS system. We've also dived deep into Mongoose and schema design, learning how to structure our database and design schemas for our CMS system.

We started with an introduction to MongoDB Cloud Atlas, Node.js, and Mongoose, setting the stage for our practical guide. We then moved on to setting up our environment, installing the necessary software and tools, and setting up MongoDB Cloud Atlas and our Node.js environment.

Next, we built a CMS system as an example, providing an overview of the system and designing the application structure. We then delved into Mongoose and schema design, learning about Mongoose, designing schemas for our CMS system, and discussing best practices for structuring databases and designing schemas.

After that, we implemented our CMS system, providing a step-by-step guide to building the system and incorporating MongoDB Cloud Atlas and Mongoose. We then prepared our application for deployment and deployed it using MongoDB Cloud Atlas.

Finally, we discussed troubleshooting and common issues, covering common issues during deployment and while using MongoDB Cloud Atlas and Mongoose, and how to troubleshoot these issues. We also provided documentation for our CMS system, explaining how to use our Article model.

As a final note, remember that learning is a continuous process. There are many resources available to deepen your understanding of these topics. The official MongoDB documentation, Mongoose documentation, and Node.js documentation are great places to start.

Thank you for joining us on this journey. Happy coding!

Top comments (2)

Collapse
 
technologymoment profile image
TechnologyMoment

Well-written article that deserves a like!

Collapse
 
aradwan20 profile image
Ahmed Radwan

Thank you