Day 2/14: Routing, Controllers & Middlewares
Topics I covered today:
> Routing
> Controllers
> Middlewares
> Request/Response objects
From chaos to structure....
1/ What is Routing?
The problem:
> You have 50 different endpoints
> /login, /signup, /users, /posts, etc.
> How does server know which function to call?
Solution: Router maps URLs to functions.
Example:
GET /users → getUsersFunction
POST /login → loginFunction
Router = traffic controller for requests.
Basic Routing Flow
2/ Route Structure:
Basic route:
> app.get('/users', function)
>
app.post('/login', function)
Dynamic route:
> app.get('/users/:id', function)
What this means:
/users/42 → id = 42
/users/99 → id = 99
Colon (:) makes it dynamic.
One route, handles all user IDs.
3/ Request Object (req):
What you can read from incoming requests:
> req.params:
/users/:id →
req.params.id
Dynamic route data
> req.query:
/users?page=2 →
req.query.page
Filter parameters
> req.body:
POST data { email, password }
> req.headers:
Authorization token
Content-Type
Everything you need is in req.
4/ Response Object (res):
How you send data back:
> res.json():
Send JSON response Most common for APIs
> res.status():
Set status code 200, 404, 500, etc.
> Chaining:
res.status(201).json({ success: true })
Simple, clean responses.
5/ What are Controllers?
The problem:
All logic in route files = messy Hard to test Code repeats
Solution:
> Separate logic into controllers.
> Clean routes, organized code.
Controller Example:
> Route file:
router.get('/users/:id', getUser)
router.post('/users', createUser)
> Controller file:
export const getUser = (req, res) => {
const userId =
req.params.id
// fetch from DB
res.json({ userId })
}
Routes = map Controllers = logic
Separation makes code maintainable.
7/ What are Middlewares?
Middleware = function that runs BEFORE your controller.
Used for:
> Logging requests
> Checking authentication
> Validating data
> Parsing body
Structure:
(req, res, next) => {
// do something
next() // pass to next function
}
Think:
Security checkpoint before entering the building.
> Each middleware does ONE job
> Controller only handles core logic
8/ Middleware Example:
> Logger middleware:
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`)
next()
}
Using it:
app.use(logger) // applies to all routes
Now every request gets logged automatically.
No need to repeat console.log everywhere.
9/ Middleware Flow:
If any middleware calls next() → continues
If any middleware sends response → stops
10/ Types of Middleware:
> Built-in: express.json()
> Custom: Your own logging, validation
> Global: app.use(middleware)
> Route-specific:
router.get('/admin', authCheck, handler)
> Error-handling: (err, req, res, next) => {...}
Choose based on need.