> Backend Development

Build a robust backend with Express and MongoDB: a step-by-step guide to creating a CRUD API.
Written by Mark VincentUpdated: July 2024

Setting up a robust backend is a crucial step in developing scalable applications. This guide provides detailed instructions for creating a MongoDB cluster using MongoDB Atlas and configuring a JavaScript-based server with Express. The goal is to ensure a smooth setup process, even if you're new to backend development.

Table of Contents

  1. MongoDB Cluster Setup
  2. Server Configuration
  3. Routes
  4. Models + Schema
  5. Connecting the MongoDB Cluster
  6. Finishing Up

1. MongoDB Cluster Setup

MongoDB is a NoSQL database, meaning it stores data in a flexible, JSON-like format (called BSON) instead of the traditional rows and columns used in SQL databases. It was created in 2007 by developers at 10gen (now MongoDB, Inc.) as a response to the growing need for scalability in modern applications. MongoDB allows for dynamic, schema-less documents, making it ideal for projects where data structure may change over time.

To set up your MongoDB database, follow these steps:

  1. Visit the MongoDB Atlas website, fill out the registration form, and verify your email.
  2. If you already have an account, simply log in.
  3. Once logged in, click on Build a Database and select the Shared (Free) option.
  4. Choose AWS as the cloud provider and select the North American region closest to your location.
  5. Skip the remaining options and click Create Cluster. This may take a few minutes to complete.
  6. Once your cluster is ready, navigate to the Connect option, select Allow Access from Anywhere, and click Add IP Address.
  7. Create a username and password, and save these credentials in a secure location.
  8. Choose the Connect method, and select MongoDB Compass.
  9. Ignore the download suggestion in step 1 and copy your CONNECTION STRING. Save this string along with your username and password for future use.

MongoDB Atlas is the cloud version of MongoDB, offering automatic scaling, backups, and performance monitoring. You don’t have to worry about managing the database infrastructure, which makes it a great choice for developers who want to focus on building features rather than dealing with server maintenance.

2. Server Configuration

Express is a minimalist web framework for Node.js, created in 2010 by TJ Holowaychuk. It simplifies the process of building web applications and APIs by providing tools for handling HTTP requests, defining routes, and managing middleware. Express is lightweight and unopinionated, meaning it gives developers the flexibility to structure their projects in whatever way best suits their needs. It has become one of the most popular server-side frameworks in the JavaScript ecosystem.

"No Magic, Just JavaScript"

Now that your MongoDB cluster is set up, it’s time to configure your server using Express.

  1. Initialize your project by creating a new directory and setting up npm:

    mkdir backend cd backend npm init -y

    This will generate a package.json file.

  2. Install the necessary dependencies:

    npm install express mongoose cors npm install nodemon --save-dev
    • express: A minimalist web framework for Node.js.
    • mongoose: An Object Data Modeling (ODM) library for MongoDB.
    • cors: Middleware to enable Cross-Origin Resource Sharing (CORS) requests.
    • nodemon: Automatically restarts the server when file changes are detected.
  3. Configure package.json with start scripts and set ES6 modules support:

    { "type": "module", "scripts": { "start": "node index.js", "start:dev": "nodemon --inspect index.js" } }
  4. Create the foundational structure by adding .gitignore and index.js files:

    touch .gitignore touch index.js

    In .gitignore, make sure to exclude node_modules:

    /node_modules
    
  5. In index.js, set up your Express server:

    import express from 'express'; const app = express(); const port = process.env.PORT || 5000; app.listen(port, () => console.log(`Server running on port ${port}`));
  6. Start your server with:

    npm run start:dev

You should see Server running on port 5000 in your terminal.

3. Routes

Routes define how your server handles requests, and they map incoming HTTP requests to specific actions (like sending back a response or manipulating data).

  1. Add middleware to handle JSON requests in index.js:

    app.use(express.json());
  2. Add a simple GET route that responds with a message:

    app.get('/test', (req, res) => { // Respond with the first word sent over the internet res.send('lo'); });

Now, when you navigate to http://localhost:5000/api/test, you should see the message lo - the first word sent over the internet! This is the basis for building more complex routes, such as creating, reading, updating, and deleting data (CRUD operations).

4. Models + Schema

In MongoDB, data is stored as documents in collections. These documents are similar to JSON objects, but there are no strict rules about how they should be structured. This is where schemas come in. Schemas are a way of enforcing a certain structure on your data, so you can define rules like "every user must have a name and email address." Mongoose allows you to define schemas easily, and helps you work with structured data while still benefiting from MongoDB's flexibility.

Let’s set up Mongoose models to structure your data.

  1. Create a models directory, and inside it, create a file called data.js:

    mkdir models touch models/data.js
  2. In models/data.js, define a simple Mongoose schema. This can be used to model any type of data (e.g., users, blog posts, etc.):

    import mongoose from 'mongoose'; const Schema = mongoose.Schema; const DataSchema = new Schema({ title: { type: String, required: true }, content: { type: String, required: true } }, { timestamps: true }); export const Data = mongoose.model('Data', DataSchema);

This schema will handle generic data, which can be customized for different purposes. Schemas are useful for defining a consistent structure for your data, while Mongoose handles how that data gets saved and retrieved from MongoDB.

Mongoose is an ODM (Object Document Mapper) for MongoDB and Node.js, created in 2010. It provides a way to structure MongoDB documents and enforce schemas on data, even though MongoDB itself is schema-less. With Mongoose, you can define models (representing collections) and schemas (the structure of documents), which makes data validation and relationship management much much simpler.

5. Connecting the MongoDB Cluster

  1. Create a config directory and add a keys.js file to store your MongoDB connection string:

    mkdir config touch config/keys.js
  2. In keys.js, paste your MongoDB connection string (replace YOUR_CONNECTION_STRING with the one you saved earlier):

    export const MONGO_URI = 'YOUR_CONNECTION_STRING';
  3. Now, connect MongoDB in index.js by importing the URI and using Mongoose to establish the connection:

    import mongoose from 'mongoose'; import { MONGO_URI } from './config/keys.js'; mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => console.log('MongoDB connected')) .catch((err) => console.error('MongoDB connection error:', err));
  4. Restart your server and test the connection.

6. Finishing Up

Congratulations! You’ve just built a robust backend using MongoDB and Express that can serve as the foundation for any project.

Why Use This Setup?

  • Flexibility: MongoDB’s document-based model is perfect for applications that need to evolve their data structure over time.
  • Scalability: MongoDB can scale horizontally across multiple servers, making it ideal for large-scale applications.
  • Simplicity: Express, with its minimalist design, allows you to build servers quickly while still giving you the flexibility to customize routes, handle middleware, and scale as needed.

Next Steps

  • Add more routes for specific functionalities (e.g., handling user authentication, creating REST APIs).
  • Create additional models for various data types you need in your application (like users, products, or orders).
  • Enhance your server with middleware for validation, authentication, and logging.

You’re now ready to start building dynamic, data-driven applications with your new backend setup!

Happy Hacking!