Backend Development Request Lifecycle Express / Node.js

How Backend Works — From Request to Response

Most developers understand HTTP and REST in isolation — but struggle to explain what actually happens inside a backend when a user clicks a button. This module traces a real request through every layer of a backend application: router → middleware → controller → service → database → response. You will trace code, debug broken requests, and complete a real enrollment challenge.

Context: Full Stack / Backend Career
Stack: Node.js + Express
Est. Time: 50–65 Minutes

1. What Is the Backend?

The application layer between clients and data — not just "the database"

A common beginner mistake is thinking the backend is just "where data is stored." The backend is the application layer — it sits between clients and data, and is responsible for all the logic that makes an application work correctly and securely. The database stores raw data. The backend decides who can access it,what they can see, how it must be validated, and what rulesapply before anything is read or written.

🖥️ Frontend (Client-Side)
  • Runs in the user's browser
  • Handles UI rendering and user interaction
  • Sends requests to the backend API
  • Displays data returned by the backend
  • Cannot be trusted for security decisions
⚙️ Backend (Server-Side)
  • Runs on a server — outside the user's control
  • Processes all application logic
  • Validates input, checks authentication
  • Applies business rules and authorisation
  • Reads / writes the database securely
  • Returns structured HTTP responses
🔄 Example — Learning Platform:
User opens the platform → Frontend sends GET /api/courses
→ Backend checks authentication → queries database → filters enrolled courses
→ transforms rows into clean JSON → returns 200 OK
→ Frontend renders the course list

The database never speaks directly to the frontend. The backend is the trusted middle layer.

2. The Complete Request Lifecycle

From client click to database and back — every layer explained

When a client sends GET /api/courses/42, it does not go directly to the database. It travels through a precise sequence of layers inside the backend application. Each layer has a specific, non-overlapping responsibility.

🌐CLIENTBrowser / Mobile App / Frontend
↓
🔗HTTP REQUESTGET /api/courses/42 + headers
↓
🖥️WEB SERVERNode.js / Uvicorn — receives connection
↓
🔀ROUTERMatches URL pattern → selects handler
↓
🛡️MIDDLEWAREAuth, logging, rate limit, CORS
↓
🎮CONTROLLERValidates request, calls service layer
↓
⚙️SERVICE / BUSINESS LOGICApplies rules, transforms data
↓
🗄️DATABASESQL / NoSQL query executed here
↓
📤HTTP RESPONSE200 OK with JSON body
↓
🌐CLIENTReceives and renders the data
Request carries
  • method — GET, POST, PUT, DELETE
  • URL + params — /api/courses/42
  • headers — Authorization, Content-Type
  • body — JSON payload (POST/PUT)
  • query — ?page=1&limit=10
Response carries
  • status code — 200, 201, 400, 401, 404, 500
  • headers — Content-Type, CORS headers
  • body — JSON, HTML, or binary

3. What the Backend Actually Does

Application logic — far more than just database access

Most developers underestimate how much work a backend does per request. The database access is just one step — often the last. Before reaching the database, the backend applies layers of logic that make the application correct, secure, and consistent.

POST /api/orders — what the backend does step by step
// Incoming: POST /api/orders
// Body: { "productId": 42, "quantity": 2 }

// ── Step 1: Validate input ────────────────────────────────
if (!body.productId || body.quantity < 1) {
  return res.status(400).json({ error: 'Invalid order data' });
}

// ── Step 2: Check authentication ──────────────────────────
if (!req.user) {
  return res.status(401).json({ error: 'Login required' });
}

// ── Step 3: Apply business rules ──────────────────────────
const product = await productService.getById(body.productId);
if (product.stock < body.quantity) {
  return res.status(400).json({ error: 'Insufficient stock' });
}

// ── Step 4: Calculate totals ──────────────────────────────
const total = product.price * body.quantity;

// ── Step 5: Write to database ─────────────────────────────
const order = await orderService.create({
  userId:    req.user.id,
  productId: body.productId,
  quantity:  body.quantity,
  total
});

// ── Step 6: Return response ───────────────────────────────
return res.status(201).json({ orderId: order.id, total });
💡 Key Insight: The backend is the enforcer of correctness. The frontend can be modified by users, bypassed by API clients, or called by automated scripts. The backend is the only trustworthy layer — it must validate everything and enforce every rule regardless of where the request came from.

4. Why Frontend Never Talks Directly to the Database

The backend as a controlled access layer

❌ Without a Backend
  • Any user can query any table
  • No authentication enforcement
  • Database credentials exposed to browser
  • No business rules applied
  • Raw database schema visible to users
✅ With a Backend API
  • Backend decides who can access what
  • Credentials never leave the server
  • Business rules enforced consistently
  • Only safe, transformed data returned
  • Internal schema hidden from clients
GET /api/users/42 — what the backend does before returning data
async function getUser(req, res) {
  const targetId   = req.params.id;
  const currentUser = req.user; // set by authMiddleware

  // 1. Authorization check
  if (currentUser.id !== targetId && !currentUser.isAdmin) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // 2. Database query (only this layer touches DB)
  const row = await db.users.findById(targetId);

  // 3. Select only safe fields — NEVER expose passwordHash
  const safeUser = {
    id:        row.id,
    name:      row.name,
    email:     row.email,
    createdAt: row.created_at
    // passwordHash, internalFlags NOT included
  };

  return res.status(200).json(safeUser);
}

5. Server-Side vs Client-Side

Where each layer runs and what it is responsible for

🌐 Client (Browser)
  • Renders HTML, CSS, JavaScript UI
  • Handles user interaction (clicks, forms)
  • Sends HTTP requests to backend APIs
  • Receives and displays response data
  • Cannot be trusted for security decisions
  • Anyone can inspect or modify the code
⚙️ Server (Backend)
  • Runs in a controlled server environment
  • Processes incoming HTTP requests
  • Applies authentication & authorisation
  • Enforces all business rules
  • Accesses databases and external services
  • Returns structured HTTP responses
"Show my enrolled courses" — full flow
// BROWSER ──────────────────────────────────────────────────
fetch('/api/courses/enrolled', {
  headers: { 'Authorization': `Bearer ${token}` }
});

// BACKEND — each step runs in order ────────────────────────
// 1. authMiddleware: identifies user from token
// 2. router: matches /api/courses/enrolled
// 3. controller: delegates to service
// 4. service: queries enrollments table for req.user.id
// 5. service: fetches course details for each enrollment
// 6. service: transforms and returns clean data array
// 7. controller: res.status(200).json(courses)

// BROWSER ───────────────────────────────────────────────────
.then(res => res.json())
.then(courses => renderCourseList(courses));

6. Live Request Tracer

Trace GET /api/users/42/orders through 5 real Express files

Below is a real 5-file Express backend. Click ▶ Start Trace to walk through the request step by step — the active file and highlighted lines update automatically. You can also click any filename tab to read the code directly.

🔍 Request Tracer — GET /api/users/42/ordersClick ▶ Start Trace to begin
1// router.js — Express router
2const express = require('express');
3const router = express.Router();
4const { authMiddleware } = require('./middleware');
5const ordersController = require('./controller');
6
7// ❶ Request enters here — route matching
8router.get(
9 '/api/users/:userId/orders',
10 authMiddleware, // ❷ middleware runs first
11 ordersController.getOrders // ❸ then controller
12);
13
14module.exports = router;
Execution Steps
❶ Request enters router
Route matches GET /api/users/:userId/orders
❷ Middleware runs
Auth token checked — user identified
❸ Route passes to controller
next() called — execution continues
❹ Controller executes
Permission check, delegates to service
❺ Service applies business logic
Calls DB layer, transforms result
❻ Database queried
SQL executed against PostgreSQL
❼ Response built & sent
200 JSON response returned to client

7. Debug the Request Flow

Five realistic failure scenarios — identify exactly where each breaks

Each scenario shows a request that fails somewhere in the backend lifecycle. Read the code, identify which layer the failure occurs in, and select the correct answer.

🐛 Debug the Request Flow0/5 answered · Score: 0
Request: GET /api/user/42/orders

The client sends GET /api/user/42/orders but the route is /api/users/:userId/orders. What happens?

// Router has this route defined:
router.get('/api/users/:userId/orders', auth, controller.getOrders);

// ❌ Client sends:
// GET /api/user/42/orders
//           ↑ missing 's'

// What does Express return?
1 / 5

8. Mini Challenge — Trace a Course Enrollment

POST /api/courses/42/enroll — trace + find the intentional bug

🎯 Your Tasks: ① List each layer the request flows through.  ② Find the exact bug — which line, what is wrong.  ③ Explain what the client receives when the bug fires.  ④ Write the one-line fix.

Flow: Read → Trace → Identify Bug → Explain → Show Solution
🎯 Mini Challenge — POST /api/courses/42/enrollTrace + Debug
Output
Click ▶ Run — then read the comments and answer the 4 questions in the code

9. Recap — The Backend Mental Model

Key terms and the complete request lifecycle in one view

Backend
Server-side application layer between clients and data. The only trusted, controlled environment.
Router
Matches incoming URL + HTTP method to the correct controller handler. First layer after the web server.
Middleware
Functions that run before the route handler: auth checks, logging, CORS, rate limiting.
Controller
Receives the validated request, calls the service layer, builds the HTTP response.
Service Layer
Contains business logic — rules, calculations, decisions. Delegates DB access to the data layer.
Data Layer (DB)
The only layer that executes SQL/NoSQL queries. Keeps DB logic isolated from business logic.
Business Logic
Rules unique to the application: stock checks, permission rules, pricing calculations.
Authorisation
Server-side: "Can this authenticated user perform this action on this specific resource?"
Status Code
200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Error.
Request Lifecycle
Router → Middleware → Controller → Service → Database → Response. Every request follows this path.
CLIENT (browser / app)
  ↓  HTTP Request (method + URL + headers + body)
SERVER
  ↓  WEB SERVER    — receives TCP connection
  ↓  ROUTER        — matches URL pattern
  ↓  MIDDLEWARE     — auth, logging, rate limit, CORS
  ↓  CONTROLLER    — validates, delegates
  ↓  SERVICE       — business logic, rules, transforms
  ↓  DATABASE      — SQL/NoSQL query executed
  ↑  Data returned up through all layers
  ↑  HTTP RESPONSE — status + headers + JSON
CLIENT
  ←  Renders data received from backend

"The backend is the application layer that sits
 between clients and the data/services they need."