>_
EngineeringNotes
← Back to All Backend Concepts
Concept 09

Handlers & Controllers

The primary entry points for your application logic, responsible for receiving the HTTP request, extracting data, and orchestrating the response cycle.

01

Request Entry and Routing

When an HTTP request traverses the network and reaches the server, it is initially completely raw. It must be processed by a routing mechanism, which serves as the server's internal switchboard. Based on the URL pathway and the specific HTTP method (GET, POST, PUT, DELETE), the router strictly identifies the correct Handler (or Controller) perfectly mapped to manage that exact request.

The Router Switchboard
HTTP POST /api/users
🔀 Router matches path & method
"/posts"
(Ignored)
"/users"
UserController
"/auth"
(Ignored)
routes/index.js
const router = express.Router(); // The router binds URL definitions to specific handlers router.get("/api/users/:id", userController.getUserById); router.post("/api/users", userController.createUser);
02

The Role of Handlers

controllers/userController.js
export const createUser = async (req, res, next) => { try { // 1. EXTRACT DATA from the request environment const userData = req.body; const utmSource = req.query.source; // 2. DELEGATE to the Service Layer const newUser = await userService.registerUser(userData); // 3. RESPOND back to the client return res.status(201).json(newUser); } catch (error) { next(error); // Forward to global error handler } };

Handlers are the primary entry points containing the HTTP framework's logic. From the runtime environment, they receive the Request and Response objects.

🎯 Core Responsibilities
  • Extraction: Unpacking req.body, Query Parameters, and Path Variables.
  • Deserialization Binding: Converting raw incoming network bytes (like JSON) into local platform-specific types (like a nested Struct in Go/Rust or a verified Object in JS). If this base conversion fails, handlers instantly throw a 400 Bad Request.
  • Delegation: Passing the heavily refined data downward into the proper Business Layer functions.
A handler should ideally rarely contain heavy computational logic, complex loops, or direct database queries itself. It strictly serves as the HTTP translating manager.
03

Service & Repository Layers

Once the controller handler perfectly extracts and shapes the input, it hands the pristine data directly to the deeper layers. Architecting this separation of concerns is what allows code to be scalable, testable, and reusable.

⚙️
The Service Layer
Business Logic Hub

Where the actual magic happens. This layer contains the core rules of your universe. It calculates taxes, fires off email requests, handles complex conditional workflows, and manages the domain.

Strict Rule: Must be 100% blind to HTTP. It should never know what a res.send() or a req.body is.
🗄️
The Repository Layer
Data Access Object (DAO)

The absolute lowest level, completely insulated from logic. Its strictly solitary job is to execute highly specific operations against the Database cluster using SQL or an ORM.

Goal: If you migrate from MongoDB to PostgreSQL, only this specific layer code changes.

Why 204 No Content? Many operations, particularly DELETE mapping to Repository removal methods, logically succeed but inherently have zero fresh data to return. Controllers perfectly map this outcome by issuing a 204 No Content status code to intelligently save network bandwidth.