Skip to main content
MongoDB
CHAPTER 30 Beginner

Capstone Project: Building a Complete API

Updated: May 16, 2026
15 min read

# CHAPTER 30

Capstone Project: Building a Complete API

1. Introduction

Congratulations! You have journeyed from the absolute basics of NoSQL documents to the complex architecture of Sharded Clusters. To solidify your expertise, we will synthesize everything you have learned into a single, comprehensive Capstone Project. You will act as the Lead Backend Architect for a new online learning platform (similar to Udemy). You will design the schema, enforce data integrity, write the Express.js API routes, and execute complex analytics pipelines.

2. Project Requirements

The platform requires the following features:
  1. 1. Schema Design: A secure courses collection with strict JSON Validation.
  1. 2. Database Connection: A robust Node.js connection script utilizing MongoClient.
  1. 3. Create Route: An API endpoint to insert a new course.
  1. 4. Read Route: An API endpoint to fetch a specific course by ID.
  1. 5. Update Route: An API endpoint to add a new "Student" to a course's enrollment array.
  1. 6. Analytics Route: An endpoint utilizing the Aggregation Framework to calculate total platform revenue.

3. Step 1: Schema Design & Validation (Chapter 18)

Before writing backend code, we must lock down the database. Connect to your mongosh terminal (or Atlas interface) and execute this validation script to protect the courses collection.
javascript
1234567891011121314151617
db.createCollection("courses", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: [ "title", "price", "instructor" ],
         properties: {
            title: { bsonType: "string", description: "must be string" },
            price: { bsonType: "double", minimum: 0, description: "must be a positive number" },
            instructor: { bsonType: "string" },
            students_enrolled: { 
                bsonType: "array", 
                items: { bsonType: "string" } 
            }
         }
      }
   }
});

4. Step 2: The Database Connection (Chapter 24)

Create your Node.js server.js file. Establish a global connection pool using async/await to ensure the API doesn't crash from network latency.
javascript
123456789101112131415161718192021
const express = require('express');
const { MongoClient, ObjectId } = require('mongodb');
require('dotenv').config();

const app = express();
app.use(express.json());

const uri = process.env.MONGO_URI; // Secret URI!
let db;

async function connectDB() {
    try {
        const client = new MongoClient(uri);
        await client.connect();
        db = client.db("learning_platform");
        console.log("MongoDB Connected Successfully");
    } catch (err) {
        console.error("Database connection failed", err);
        process.exit(1);
    }
}

5. Step 3: Create & Read Routes (Chapters 6 & 7)

Implement the core CRUD functionality. Ensure you handle the ObjectId conversion securely.
javascript
12345678910111213141516171819202122
// CREATE a Course (POST)
app.post('/api/courses', async (req, res) => {
    try {
        // Enforce a default empty array for students
        const newCourse = { ...req.body, students_enrolled: [] }; 
        const result = await db.collection("courses").insertOne(newCourse);
        res.status(201).json({ success: true, courseId: result.insertedId });
    } catch (error) {
        res.status(400).json({ error: "Validation Failed or Bad Data" });
    }
});

// READ a Course by ID (GET)
app.get('/api/courses/:id', async (req, res) => {
    try {
        const course = await db.collection("courses").findOne({ _id: new ObjectId(req.params.id) });
        if (!course) return res.status(404).json({ error: "Course Not Found" });
        res.status(200).json(course);
    } catch (error) {
        res.status(400).json({ error: "Invalid ID Format" });
    }
});

6. Step 4: The Array Update Route (Chapter 17)

When a user buys a course, we don't rewrite the document. We use the $push operator to add their username into the existing students_enrolled array.
javascript
12345678910111213
// UPDATE: Enroll a Student (PUT)
app.put('/api/courses/:id/enroll', async (req, res) => {
    try {
        const studentName = req.body.username;
        const result = await db.collection("courses").updateOne(
            { _id: new ObjectId(req.params.id) },
            { $push: { students_enrolled: studentName } } // Surgically push to array!
        );
        res.status(200).json({ success: true, message: "Student Enrolled!" });
    } catch (error) {
        res.status(500).json({ error: "Server Error" });
    }
});

7. Step 5: The Analytics Pipeline (Chapter 15)

The CEO wants to know how much money the platform has made. We construct an Aggregation Pipeline to crunch the math.
javascript
1234567891011121314151617181920212223
// GET Total Platform Revenue
app.get('/api/analytics/revenue', async (req, res) => {
    try {
        const pipeline = [
            // Stage 1: Create a temporary field that counts the array length!
            { $addFields: { total_students: { $size: "$students_enrolled" } } },
            
            // Stage 2: Multiply the price by the number of students
            { $addFields: { course_revenue: { $multiply: ["$price", "$total_students"] } } },
            
            // Stage 3: Group everything together and SUM the total revenue!
            { $group: {
                _id: "Total Revenue",
                platform_total: { $sum: "$course_revenue" }
            }}
        ];

        const report = await db.collection("courses").aggregate(pipeline).toArray();
        res.status(200).json(report);
    } catch (error) {
        res.status(500).json({ error: "Analytics Pipeline Failed" });
    }
});

8. Booting the Server

Finally, initialize the connection and start the Express server.
javascript
12345
connectDB().then(() => {
    app.listen(3000, () => {
        console.log("Learning Platform API running on port 3000");
    });
});

9. Final Review

Look at the code you have written.
  • You designed a NoSQL schema that enforces data integrity natively in the database.
  • You separated concerns, maintaining high-performance connections.
  • You mapped REST protocols to surgical $push array updates.
  • You built an advanced BSON math pipeline that groups and processes data instantly.

You are no longer a beginner. You are a highly capable NoSQL Database Engineer.

10. Conclusion and Next Steps

You have completed the comprehensive MongoDB learning roadmap. Where do you go from here?
  1. 1. Learn Mongoose: Transition from the Native Node.js driver to Mongoose ORM to simplify your backend code.
  1. 2. Master React: Complete the MERN stack by building a beautiful frontend UI that consumes this exact API you just built.
  1. 3. Get Certified: Consider pursuing the official "MongoDB Certified Developer" or "MongoDB Certified DBA" credentials to prove your expertise to employers.

Thank you for choosing this platform for your database journey. Keep building, keep optimizing, and welcome to the world of NoSQL.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·