Episode 11 of 12
Express Router & MVC
Learn how to organize your Express app using the Router and the MVC (Model-View-Controller) architectural pattern.
As your application grows, keeping everything in one file becomes unmanageable. The Express Router and MVC pattern help you organize your code into a clean, maintainable structure.
Express Router
The Router lets you split routes into separate files:
// routes/blogRoutes.js
const express = require('express');
const router = express.Router();
const Blog = require('../models/blog');
router.get('/', (req, res) => {
Blog.find().sort({ createdAt: -1 })
.then(blogs => res.render('blogs/index', { blogs }))
.catch(err => console.log(err));
});
router.post('/', (req, res) => {
const blog = new Blog(req.body);
blog.save()
.then(() => res.redirect('/blogs'))
.catch(err => console.log(err));
});
router.get('/:id', (req, res) => {
Blog.findById(req.params.id)
.then(blog => res.render('blogs/details', { blog }))
.catch(err => console.log(err));
});
module.exports = router;
// app.js
const blogRoutes = require('./routes/blogRoutes');
app.use('/blogs', blogRoutes);
The MVC Pattern
MVC separates your application into three layers:
- Model — Data structure and database logic (Mongoose schemas)
- View — What the user sees (EJS templates)
- Controller — Handles requests and connects models to views
Creating Controllers
// controllers/blogController.js
const Blog = require('../models/blog');
const blog_index = (req, res) => {
Blog.find().sort({ createdAt: -1 })
.then(blogs => res.render('blogs/index', { blogs }))
.catch(err => console.log(err));
};
const blog_details = (req, res) => {
Blog.findById(req.params.id)
.then(blog => res.render('blogs/details', { blog }))
.catch(err => res.status(404).render('404'));
};
const blog_create_post = (req, res) => {
const blog = new Blog(req.body);
blog.save()
.then(() => res.redirect('/blogs'))
.catch(err => console.log(err));
};
module.exports = {
blog_index,
blog_details,
blog_create_post
};
Project Structure
project/
├── app.js
├── models/
│ └── blog.js
├── views/
│ ├── partials/
│ └── blogs/
├── controllers/
│ └── blogController.js
├── routes/
│ └── blogRoutes.js
└── public/
└── styles.css
This clean separation makes your code easier to maintain, test, and scale.