Express Routing & Controllers
In the previous lesson, we created a basic server. But as your project grows, you can't put 100 different routes in a single server.js file. Routing allows us to split our application into small, manageable pieces.
1. The Anatomy of a Route
A route in Express follows this structure:
app.METHOD(PATH, HANDLER)
app: The instance of express.METHOD: The HTTP verb (GET, POST, PUT, DELETE).PATH: The URL on the server (e.g.,/api/users).HANDLER: The function that runs when the route is matched.
2. Route Parameters
Sometimes parts of your URL are dynamic. For example, in https://codeharborhub.github.io/our-team/details/?member=ajay-dhangar, the "ajay-dhangar" part changes depending on the user. We handle this using Params.
// The colon (:) tells Express this part is a variable
app.get('/user/:username', (req, res) => {
const name = req.params.username;
res.send(`Viewing profile of: ${name}`);
});
3. Query Strings
Query strings are the key-value pairs you see after a ? in a URL (e.g., /search?club=cricket&sort=new). These are optional and used for filtering or searching.
app.get('/search', (req, res) => {
const { club, sort } = req.query;
res.send(`Searching for ${club} sorted by ${sort}`);
});
4. The Express Router
To keep our code clean, we use express.Router() to group related routes into separate files. This is how we organize large projects at the Hub.
Step 1: Create a route file
const express = require('express');
const router = express.Router();
router.get('/profile', (req, res) => res.send('User Profile'));
router.get('/settings', (req, res) => res.send('User Settings'));
module.exports = router;
Step 2: Use it in your main server
const express = require('express');
const app = express();
const userRouter = require('./routes/userRoutes');
// All routes in userRouter will now start with /user
app.use('/user', userRouter);
5. Controllers: Separating Logic
To be a professional "Master" developer, you shouldn't put your logic inside the route file. Instead, we use Controllers.
- Route file: Defines the URL.
- Controller file: Contains the function logic.
Example Structure:
exports.getUserProfile = (req, res) => {
// Logic to fetch user from database would go here
res.json({ name: "Ajay", role: "Developer" });
};
Now, in your route file, you can import this controller:
const userController = require('../controllers/userController');
router.get('/profile', userController.getUserProfile);
Practice: The Mini-Library API
Try to create a router for a "Book" system:
- Create a
bookRoutes.jsfile. - Add a GET route for
/allto see all books. - Add a GET route for
/:idto see a specific book by its ID. - Link it to your
server.jsunder the path/api/books.
When responding to a route, always send the correct status code.
200: OK (Success)201: Created (Success after POST)404: Not Found500: Server Error
const express = require('express');
const router = express.Router();
router.get('/all', (req, res) => {
res.json([{ id: 1, title: "The Great Gatsby" }, { id: 2, title: "To Kill a Mockingbird" }]);
});
router.get('/:id', (req, res) => {
const bookId = req.params.id;
// In a real app, you'd fetch the book from the database
if (bookId === "1") {
res.json({ id: 1, title: "The Great Gatsby" });
} else if (bookId === "2") {
res.json({ id: 2, title: "To Kill a Mockingbird" });
} else {
res.status(404).send("Book not found!");
}
});
module.exports = router;