Lesson 23 +10 XP

Project 3: Micro Blog API with Mongoose & Security

Build a Production Mongoose & Security Blog API

In this project, you will combine Mongoose database integration with security best practices like Helmet, CORS, and Rate Limiting.

Project Code Overview

const express = require("express");
const mongoose = require("mongoose");
const helmet = require("helmet");
const cors = require("cors");
const rateLimit = require("express-rate-limit");

const app = express();

// Security Middlewares
app.use(helmet());
app.use(cors());
app.use(express.json());

// Rate Limiting
app.use("/api/", rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));

// Mongoose Schema & Model
const postSchema = new mongoose.Schema({
  title: { type: String, required: true, trim: true },
  content: { type: String, required: true },
  author: { type: String, default: "Anonymous" },
  likes: { type: Number, default: 0 },
  createdAt: { type: Date, default: Date.now }
});

const Post = mongoose.model("Post", postSchema);

// CREATE POST
app.post("/api/posts", async (req, res, next) => {
  try {
    const post = await Post.create(req.body);
    res.status(201).json({ status: "success", data: post });
  } catch (err) {
    next(err);
  }
});

// GET ALL POSTS WITH PAGINATION
app.get("/api/posts", async (req, res, next) => {
  try {
    const page = Number(req.query.page) || 1;
    const limit = Number(req.query.limit) || 5;
    const skip = (page - 1) * limit;

    const posts = await Post.find().sort({ createdAt: -1 }).skip(skip).limit(limit);
    const total = await Post.countDocuments();

    res.status(200).json({ status: "success", page, totalPages: Math.ceil(total / limit), data: posts });
  } catch (err) {
    next(err);
  }
});

// Global Error Handler
app.use((err, req, res, next) => {
  res.status(err.statusCode || 500).json({ status: "error", message: err.message });
});

TL;DR

  • Combine Mongoose database models with pagination (skip and limit).
  • Protect APIs with helmet, cors, and rate limiting.