Appearance
Node.js & Backend Development
Design, secure, test, and deploy scalable server-side REST APIs using Node.js, Express, MongoDB, PostgreSQL + Prisma, JWT Authentication, Redis, and Jest.
15Weeks
5Stages
70+Lessons
9Projects
1Prerequisite
Download Official 2026 Curriculum PDF
Programme Overview
Every serious digital product—whether a fintech wallet, food-delivery marketplace, SaaS platform, or AI agent—relies on a resilient backend to enforce business rules, persist relational and document data, authenticate users, process background jobs, and protect sensitive records. In Course 5 of the Tech Minds Web & Full-Stack Engineering sequence, you step behind the browser to engineer production-ready servers and cloud-hosted APIs.
| Attribute | Details |
|---|---|
| Course Position | Course 5 of 5 · Web & Full-Stack Engineering Track (Backend Specialisation) |
| Duration | 15 Weeks · 5 Progressive Stages · 70+ Mentor-Led Lessons |
| Prerequisite | JavaScript Fundamentals (strong fluency in async/await, Promises, objects, and ES Modules) |
| Delivery Format | On-Campus (G5 Plaza, Sabon-Gari Road, Bwari, Abuja) & Live Interactive Online |
| Tech Stack | Node.js LTS, Express.js, MongoDB + Mongoose, PostgreSQL + Prisma ORM, JWT + bcrypt, Redis + Bull, Socket.io, Jest + Supertest, Railway / Render |
| Portfolio Output | 9 Weekly Backend Services & APIs + 1 Tested, Hardened, Cloud-Deployed Production REST API Capstone |
IMPORTANT
Before Week 1, make sure Node.js LTS, Git, VS Code, and an API client (Thunder Client or Postman) are installed via our Developer Environment Setup guide.
Curriculum Rationale
Why Node.js for backend?
Node.js pairs Google's high-performance V8 JavaScript engine with an event-driven, non-blocking I/O architecture (libuv) built specifically for high-concurrency network services, real-time WebSockets, and microservice APIs. Because you already write JavaScript from JavaScript Fundamentals, you skip learning a second syntax from scratch and focus immediately on HTTP architecture, data modelling, authentication, caching, and distributed system design—while sharing validation logic and mental models across the entire stack.
Why cover both MongoDB and PostgreSQL?
Bootcamps that teach only MongoDB leave graduates unprepared for fintech, e-commerce, and enterprise engineering roles where ACID transactions, foreign-key integrity, and SQL joins are non-negotiable. Conversely, developers who only know SQL miss out on flexible document schemas. In Stage 3, you build APIs with both MongoDB Atlas + Mongoose (NoSQL document modelling) and PostgreSQL + Prisma ORM (type-safe relational schemas, migrations, and ACID transactions), giving you architectural fluency to choose the right database for any domain.
Why include security as a full stage?
Shipping an unauthenticated or unhardened API into production is an invitation to data breaches, credential stuffing, and injection attacks. Dedicating Stage 4 (Weeks 10–12) exclusively to security ensures you implement salted bcrypt password hashing, short-lived JWT access tokens + rotating refresh tokens, Role-Based Access Control (RBAC), helmet HTTP headers, strict cors policies, express-rate-limit throttling, and input sanitisation as second nature.
What comes after this course?
Completing Node.js & Backend Development makes you job-ready for Backend Engineer or Full-Stack Software Engineer roles (when paired with React.js Mastery) and unlocks advanced infrastructure and AI tracks:
- Frontend Integration: Connect your APIs to rich client interfaces in React.js Mastery (if you took Backend first).
- Cloud & DevOps: Advance to Cloud Computing & DevOps to containerise Node services with Docker, provision AWS/Azure RDS & VPC infrastructure with Terraform, and build automated CI/CD pipelines.
- AI & MCP Engineering: Move into Agentic Software Engineering & MCP to build custom Node.js Model Context Protocol (MCP) servers, RAG pipelines, and autonomous backend agents.
- Defensive Security: Deepen your threat-modelling skills in Cyber Security & SOC Operations.
Complete 15-Week Syllabus & Code Reference
Stage 1: Node.js Runtime Foundations (Weeks 1–3)
Before installing any web framework, Stage 1 grounds you in how Node.js executes outside the browser—interacting directly with CLI arguments, environment variables, the operating system, asynchronous file streams, and raw TCP/HTTP sockets.
| Week | Core Topics & Lab Focus | Weekly Deliverable |
|---|---|---|
| Week 1 | Node.js architecture (V8 + libuv event loop) vs Browser runtime (no window or document); Node REPL; process.argv, process.env, and exit codes; CommonJS (require/module.exports) vs native ES Modules ("type": "module", import/export); npm init and semantic versioning. | Project 1: Interactive Developer Greeting & System Info CLI — Parses CLI flags and prints formatted OS/runtime diagnostics. |
| Week 2 | Core built-in modules (node:path, node:os, node:url, node:events); non-blocking file system operations with node:fs/promises (readFile, writeFile, mkdir, stat); atomic JSON read/write helpers and structured error handling (ENOENT). | Project 2: Async JSON Notes CLI — Command-line note manager supporting add, list, read, search, and remove persisted to notes.json. |
| Week 3 | How HTTP works under the hood (request line, headers, chunked body streams, status codes 200, 201, 400, 404, 405, 500); building a zero-dependency server with node:http (http.createServer); parsing incoming JSON request streams and setting Content-Type: application/json. | Project 3: Raw 3-Route Node HTTP Server — Framework-free JSON API serving /health, /api/courses, and POST /api/enquiries with proper status codes. |
Annotated Reference: Zero-Dependency node:http JSON Server & fs/promises
js
// server.js — Understanding what Express does under the hood
import http from 'node:http';
import fs from 'node:fs/promises';
import path from 'node:path';
const DATA_FILE = path.resolve('data', 'notes.json');
async function readNotes() {
try {
const raw = await fs.readFile(DATA_FILE, 'utf-8');
return JSON.parse(raw);
} catch (err) {
if (err.code === 'ENOENT') return [];
throw err;
}
}
function sendJson(res, statusCode, payload) {
res.writeHead(statusCode, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(JSON.stringify(payload));
}
const server = http.createServer(async (req, res) => {
const { method, url } = req;
if (method === 'GET' && url === '/health') {
return sendJson(res, 200, { status: 'ok', uptimeSeconds: Math.round(process.uptime()) });
}
if (method === 'GET' && url === '/api/notes') {
const notes = await readNotes();
return sendJson(res, 200, { count: notes.length, data: notes });
}
return sendJson(res, 404, { error: `Route ${method} ${url} not found` });
});
const PORT = process.env.PORT || 4000;
server.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT}`);
});Stage 2: Express.js & Clean REST API Architecture (Weeks 4–6)
Stage 2 transitions from raw http.createServer boilerplate to Express.js, teaching RESTful resource conventions, middleware pipelines, input validation, centralized error handling, and clean layered folder architecture.
| Week | Core Topics & Lab Focus | Weekly Deliverable |
|---|---|---|
| Week 4 | Installing Express & --watch mode (node --watch); RESTful verbs (GET, POST, PUT, PATCH, DELETE) and plural noun endpoints; express.json() body parser; route parameters (req.params.id) vs query strings (req.query); testing endpoints systematically in Postman / Thunder Client. | Project 4: RESTful Products Inventory API — Full CRUD endpoints with SKU lookup, stock patching, and HTTP status discipline (200, 201, 204, 400, 404). |
| Week 5 | The Express Middleware pipeline ((req, res, next) => {}); request logging (morgan & custom timing middleware); route-specific guards; async wrapper (asyncHandler) forwarding rejections to a centralized 4-argument error handler (err, req, res, next). | Project 5: Middleware-Enhanced Service API — Custom request-ID tracing, execution-time headers, API-key check middleware, and unified JSON error envelopes. |
| Week 6 | Separation of concerns: routes/, controllers/, middleware/, and validators/; modular express.Router(); declarative payload & param validation using express-validator (body(), param(), query(), validationResult). | Project 6: Structured Multi-Resource Blog API — Clean MVC controller/router split for /api/v1/posts and /api/v1/comments with full request validation. |
Annotated Reference: Express Router, express-validator & Centralized 4-Arg Error Middleware
js
// src/middleware/errorHandler.js
export class ApiError extends Error {
constructor(statusCode, message, details = null) {
super(message);
this.statusCode = statusCode;
this.details = details;
}
}
// Express identifies error-handling middleware by its exact 4 parameters: (err, req, res, next)
export function globalErrorHandler(err, req, res, next) {
const status = err.statusCode || 500;
const response = {
success: false,
message: status === 500 ? 'Internal server error' : err.message
};
if (err.details) response.errors = err.details;
if (process.env.NODE_ENV === 'development' && status === 500) {
response.stack = err.stack;
}
res.status(status).json(response);
}js
// src/routes/posts.routes.js
import { Router } from 'express';
import { body, validationResult } from 'express-validator';
import { ApiError } from '../middleware/errorHandler.js';
const router = Router();
const validatePost = [
body('title').trim().isLength({ min: 5, max: 120 }).withMessage('Title must be 5–120 chars.'),
body('content').trim().isLength({ min: 20 }).withMessage('Content must be at least 20 chars.'),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next(new ApiError(422, 'Validation failed', errors.array()));
}
next();
}
];
router.post('/', validatePost, async (req, res, next) => {
try {
const { title, content } = req.body;
const created = { id: crypto.randomUUID(), title, content, createdAt: new Date().toISOString() };
res.status(201).json({ success: true, data: created });
} catch (err) {
next(err);
}
});
export default router;Stage 3: Databases — MongoDB (Mongoose) & PostgreSQL (Prisma) (Weeks 7–9)
In-memory arrays vanish every time a server restarts. Stage 3 connects your Express controllers to cloud-hosted MongoDB Atlas and PostgreSQL, teaching schema design, relational integrity, indexing, pagination, filtering, and transactions.
| Week | Core Topics & Lab Focus | Weekly Deliverable |
|---|---|---|
| Week 7 | Document databases with MongoDB Atlas & Mongoose; environment config via dotenv; Mongoose Schemas, validation, timestamps, virtuals, and Models; async CRUD (create, find, findByIdAndUpdate, findByIdAndDelete); referencing ObjectId relations with .populate(). | Project 7: Persisted MongoDB Blog & Authors API — Cloud-backed Mongoose models linking Authors, Posts, and embedded/referenced Comments. |
| Week 8 | Relational databases with PostgreSQL & Prisma ORM; tables, primary/foreign keys, 1:N and M:N relations; authoring schema.prisma; running npx prisma migrate dev and inspecting tables in Prisma Studio; type-safe queries (prisma.task.findMany, include, select). | Project 8: PostgreSQL + Prisma Task Manager API — Relational Users, Projects, and Tasks API with enforced foreign keys and database migrations. |
| Week 9 | Production query engineering: compound database indexes for fast lookups; offset vs cursor pagination (page & limit vs cursor); dynamic filtering & multi-field sorting; atomic ACID transactions (prisma.$transaction); deterministic database seeding scripts. | Project 9a: Paginated, Indexed & Filtered Catalogue API — Supports ?category=tech&minPrice=10000&sort=-createdAt&page=2&limit=20 with metadata envelopes and seed scripts. |
Annotated Reference: Relational Schema & Paginated Query with PostgreSQL + Prisma ORM
prisma
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
enum Role {
USER
ADMIN
}
enum TaskStatus {
TODO
IN_PROGRESS
DONE
}
model User {
id String @id @default(uuid())
email String @unique
passwordHash String
role Role @default(USER)
tasks Task[]
createdAt DateTime @default(now())
}
model Task {
id String @id @default(uuid())
title String
status TaskStatus @default(TODO)
priority Int @default(2)
ownerId String
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([ownerId, status])
}js
// src/controllers/tasks.controller.js — Filtered, Sorted & Paginated Prisma Query
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export async function listUserTasks(req, res, next) {
try {
const page = Math.max(1, Number(req.query.page) || 1);
const limit = Math.min(50, Math.max(1, Number(req.query.limit) || 10));
const skip = (page - 1) * limit;
const where = {
ownerId: req.user.sub,
...(req.query.status ? { status: req.query.status } : {})
};
// Execute count and paginated fetch concurrently in a single transaction/roundtrip
const [totalItems, tasks] = await prisma.$transaction([
prisma.task.count({ where }),
prisma.task.findMany({
where,
orderBy: { createdAt: 'desc' },
skip,
take: limit,
select: { id: true, title: true, status: true, priority: true, createdAt: true }
})
]);
res.status(200).json({
success: true,
meta: {
totalItems,
currentPage: page,
totalPages: Math.ceil(totalItems / limit),
perPage: limit
},
data: tasks
});
} catch (err) {
next(err);
}
}Stage 4: Authentication, Authorization & API Security (Weeks 10–12)
Stage 4 hardens your backend for hostile public networks—implementing cryptographic password storage, stateless JWT access tokens, rotating refresh tokens, Role-Based Access Control, rate limiters, and OWASP security defences.
| Week | Core Topics & Lab Focus | Weekly Deliverable |
|---|---|---|
| Week 10 | Authentication vs Authorization; why plain-text and fast-hash (MD5/SHA) passwords fail; salted adaptive hashing with bcrypt (bcrypt.hash(pw, 12), bcrypt.compare); signing and verifying JSON Web Tokens (jsonwebtoken); protecting routes with requireAuth Bearer middleware attaching req.user. | Project 9b: Complete JWT Auth Service — /auth/register, /auth/login, and /auth/me with bcrypt hashing and protected resource ownership checks. |
| Week 11 | Role-Based Access Control (RBAC) middleware (requireRole('ADMIN', 'MODERATOR')); short-lived Access Tokens (15m) paired with httpOnly cookie / hashed database Refresh Token Rotation; token revocation & secure logout flows; password-reset token expiry design. | Project 9c: RBAC & Rotating Refresh Token System — Multi-role permissions (USER vs ADMIN) with seamless token refresh and stolen-token invalidation. |
| Week 12 | Hardening Express against OWASP API Top 10 risks: secure HTTP headers with helmet; strict origin allowlists with cors; brute-force protection on /auth/* via express-rate-limit; request payload size caps (express.json({ limit: '16kb' })); preventing SQL/NoSQL operator injection & XSS payload pollution. | Project 9: Hardened Multi-Tenant Task Manager API — Fully authenticated, RBAC-governed, rate-limited, security-audited API ready for penetration checks. |
Annotated Reference: bcrypt, JWT Auth Middleware, RBAC & Express Security Hardening
js
// src/middleware/auth.js
import jwt from 'jsonwebtoken';
import { ApiError } from './errorHandler.js';
export function requireAuth(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return next(new ApiError(401, 'Authentication token missing or malformed.'));
}
const token = authHeader.slice(7);
try {
// Explicitly pin allowed signing algorithm and secret
const decoded = jwt.verify(token, process.env.JWT_ACCESS_SECRET, {
algorithms: ['HS256']
});
req.user = decoded; // { sub: userId, role: 'USER' | 'ADMIN', iat, exp }
next();
} catch {
next(new ApiError(401, 'Invalid or expired access token.'));
}
}
export function requireRole(...allowedRoles) {
return (req, res, next) => {
if (!req.user || !allowedRoles.includes(req.user.role)) {
return next(new ApiError(403, 'Forbidden: insufficient permissions for this action.'));
}
next();
};
}js
// src/app.js — Hardened Express Application Bootstrap
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
import rateLimit from 'express-rate-limit';
import { globalErrorHandler } from './middleware/errorHandler.js';
export function createApp() {
const app = express();
// 1. Security headers & strict CORS origin policy
app.use(helmet());
app.use(
cors({
origin: process.env.ALLOWED_ORIGIN?.split(',') || ['http://localhost:5173'],
credentials: true
})
);
// 2. Cap JSON body size to mitigate memory-exhaustion payloads
app.use(express.json({ limit: '16kb' }));
// 3. Strict rate limit on authentication endpoints
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 15,
standardHeaders: true,
legacyHeaders: false,
message: { success: false, message: 'Too many login attempts. Please try again in 15 minutes.' }
});
app.use('/api/v1/auth', authLimiter);
app.get('/health', (req, res) => res.status(200).json({ status: 'healthy' }));
// ... mount /api/v1 routers here ...
app.use(globalErrorHandler);
return app;
}Stage 5: Cloud Media, Queues, Real-Time, Testing & Capstone (Weeks 13–15)
Stage 5 completes your transformation into a production backend engineer: handling multipart file uploads, offloading slow email/webhook work to Redis queues, broadcasting real-time events with Socket.io, writing Jest + Supertest integration suites (80%+ coverage), and deploying live to Railway or Render.
| Week | Core Topics & Lab Focus | Weekly Deliverable |
|---|---|---|
| Week 13 | Multipart file uploads with Multer (MIME type & file-size guards) streamed to Cloudinary; transactional HTML emails (welcome, OTP, order receipt) using Nodemailer / Resend; offloading slow tasks to background worker queues with Bull + Redis. | Cloud Media & Async Email Worker Lab — Avatar/product image upload pipeline + queued welcome/receipt email worker backed by Redis. |
| Week 14 | Bidirectional real-time events with Socket.io (rooms, authenticated handshakes, live status updates); speeding up read-heavy endpoints with Redis TTL caching & cache invalidation; automated integration testing with Jest + Supertest targeting 80%+ test coverage against an isolated test database. | Automated API Test Suite & Caching Lab — Jest + Supertest integration suite covering auth, CRUD, RBAC 403s, and validation 422s with 80%+ coverage. |
| Week 15 | Production readiness checklist: NODE_ENV=production, graceful SIGTERM shutdown, structured logging, OpenAPI / Postman documentation, cloud Postgres/MongoDB + Redis provisioning, live deployment to Railway or Render, and cohort architecture defence. | Final Cloud-Deployed Production REST API Capstone (choose 1 of 3 tracks below). |
Annotated Reference: Automated Integration Testing with Jest + Supertest
js
// tests/health-and-auth.test.js
import request from 'supertest';
import { createApp } from '../src/app.js';
const app = createApp();
describe('API Health & Auth Guard Integration Suite', () => {
it('GET /health returns HTTP 200 and healthy status', async () => {
const res = await request(app).get('/health');
expect(res.statusCode).toBe(200);
expect(res.body).toEqual({ status: 'healthy' });
});
it('rejects unauthenticated access to protected routes with HTTP 401', async () => {
const res = await request(app).get('/api/v1/tasks');
expect(res.statusCode).toBe(401);
expect(res.body.success).toBe(false);
expect(res.body.message).toMatch(/authentication token missing/i);
});
});Week 15 Capstone Project Options (Deployed to Railway or Render)
Every student designs, secures, tests (80%+ Jest/Supertest coverage), documents, and deploys one production-grade backend API on Railway or Render:
- Food Delivery & Real-Time Order Tracking Backend — Multi-role RBAC (
CUSTOMER,VENDOR,RIDER,ADMIN), restaurant & menu CRUD with Cloudinary dish uploads, transactional PostgreSQL/Prisma order placement, real-timeSocket.ioorder status broadcasts, queued email receipts (Bull + Redis), and Jest/Supertest test suite. - Scalable E-Commerce Marketplace REST API — Product catalogue with Redis-cached search/filtering/pagination, Cloudinary multi-image uploads, atomic inventory reservation inside database transactions, JWT + Refresh Token auth, webhook-ready payment verification architecture, and published Postman/OpenAPI docs.
- Event Ticketing & Booking Platform Backend — Event discovery with cursor/offset pagination, concurrent seat/ticket booking protected against overselling via database transactions, QR/booking reference generation, queued confirmation & reminder emails via Redis + Resend/Nodemailer, rate-limited auth, and 80%+ automated test coverage.
Assessment & Grading Rubric
| Assessment Component | Weight | Evaluation Criteria |
|---|---|---|
| Weekly Projects (x9) | 40% | Clean routes/ + controllers/ + middleware/ separation, proper HTTP status codes, input validation (express-validator), and secret-free Git commits (.env.example). |
| Stage Assessments (x5) | 30% | Practical coding & live API debugging reviews covering Node core, Express middleware, Mongoose/Prisma queries & migrations, and JWT/RBAC security flaws. |
| Capstone Backend System | 30% | Relational or document schema quality, JWT + Refresh Token + RBAC + Helmet/Rate-Limit hardening, Redis/Cloudinary/Email integration, 80%+ Jest/Supertest coverage, live Railway/Render URL, API docs, and architecture defence. |
Learning Outcomes
By graduating from Node.js & Backend Development, you will be able to:
- Build CLI tools, async file processors, and HTTP services directly on the Node.js runtime (
fs/promises,http, ES Modules,process). - Architect clean, maintainable Express.js REST APIs with modular routers, controllers,
express-validatorschemas, and centralized error handling. - Model, migrate, index, paginate, and query both MongoDB (Mongoose) and PostgreSQL (Prisma ORM) databases—including ACID transactions.
- Secure production APIs end to end with
bcrypt, JWT Access + Refresh Token rotation, RBAC,helmet,cors, andexpress-rate-limit. - Integrate Multer + Cloudinary uploads, Nodemailer / Resend emails, Redis + Bull background queues, Socket.io real-time channels, Jest + Supertest automated tests, and Railway / Render cloud deployments.
Tools & Learning Resources
| Tool / Platform | Role in This Course |
|---|---|
| Node.js (LTS) & Express.js | Core JavaScript server runtime and minimalist HTTP routing/middleware framework |
| MongoDB Atlas & Mongoose | Managed cloud NoSQL document database and schema/validation ODM |
| PostgreSQL & Prisma ORM | Production relational SQL database, declarative migration engine, and type-safe query client |
| Postman / Thunder Client | API request testing, environment variable collections, and published endpoint documentation |
| Redis, Bull & Socket.io | In-memory caching store, resilient background job queue, and bidirectional WebSocket server |
| Cloudinary & Resend / Nodemailer | Cloud media storage/transformation CDN and transactional email delivery |
| Jest & Supertest | Automated unit and HTTP integration testing framework with code-coverage reporting |
| Railway / Render & GitHub | Cloud PaaS platforms hosting your production Node API, managed Postgres, and Redis instances |
Next Steps in Your Track
- Complete Full-Stack Web: 4. React.js Mastery (14 Weeks) — Build tested, multi-route React SPAs that consume your Node.js REST and Socket.io APIs.
- Scale in the Cloud: Cloud Computing & DevOps (12 Weeks) — Package your Node services in Docker containers, automate GitHub Actions CI/CD, and provision AWS/Azure infrastructure with Terraform.
- Build AI Agents & MCP Servers: Agentic Software Engineering & MCP (16 Weeks) — Turn your Node.js backend skills into tool-calling AI services, RAG pipelines, and Model Context Protocol servers.
