Express.js Modular Routing

Building Scalable Express.js APIs: The Power of Modular Routing

When building a larger Express.js application, handling all your routes in a single file quickly becomes unmanageable. Instead, using modular routing can help keep your code clean, scalable, and easier to maintain. In this article, we’ll walk through setting up a modular route structure for your Express.js app.


Why Modular Routing?

As your application grows, so does the number of routes. Keeping everything in a single server.ts file leads to poor maintainability and harder debugging. By breaking routes into separate files, we achieve:

✅ Better Organization – Routes are logically grouped into folders.
✅ Scalability – New features and API versions are easier to add.
✅ Improved Readability – Developers can quickly find and manage specific routes.


Setting Up API Versioning

A good practice in REST API development is to introduce versioning. This allows users to transition between API versions without breaking their implementations. We’ll namespace our API under /v1 so that future versions (/v2, /v3, etc.) can be developed without affecting the older versions.


Step 1: Creating the Route Structure

Instead of keeping everything in server.ts, we’ll create a routes folder with a modular structure:

📂 src/routes/v1
   ðŸ“‚ tasks/ (Handles task-related routes)
   ðŸ“‚ projects/ (Handles project-related routes)
   ðŸ“„ index.ts (Main router for version 1 API)

First, create a new file src/routes/v1/index.ts and define the main router:

import express from "express";
import tasks from "./tasks";
import projects from "./projects";

const v1 = express.Router();

v1.use("/tasks", tasks);
v1.use("/projects", projects);

export default v1;

This file acts as the entry point for all routes under /v1, delegating requests to their respective modules.


Step 2: Defining Task Routes

Next, create the tasks router in src/routes/v1/tasks/index.ts:

import express from "express";
import { listTasks, getTask } from "./controller";

const tasks = express.Router();

tasks.get("/", listTasks);
tasks.get("/:id", getTask);

export default tasks;

Then, define the task controllers in src/routes/v1/tasks/controller.ts:

import { Request, Response } from "express";

export const listTasks = (req: Request, res: Response) => {
res.status(200).json([]);
};

export const getTask = (req: Request, res: Response) => {
res.status(200).json({ id: 1, name: "Task 1" });
};

🚀Boost your career with 👉 IBM Full Stack Software Developer Certificate

Step 3: Defining Project Routes

Now, define the projects router in src/routes/v1/projects/index.ts:

import express from "express";
import { listProjects, getProject, listProjectTasks } from "./controller";

const projects = express.Router();

projects.get("/", listProjects);
projects.get("/:id", getProject);
projects.get("/:id/tasks", listProjectTasks);

export default projects;

Then, create the project controllers in src/routes/v1/projects/controller.ts:

import { Request, Response } from "express";

export const listProjects = (req: Request, res: Response) => {
res.status(200).json([]);
};

export const getProject = (req: Request, res: Response) => {
res.status(200).json({ id: 1, name: "Project 1" });
};

export const listProjectTasks = (req: Request, res: Response) => {
res.status(200).json([]);
};

Step 4: Connecting Routes in server.ts

Now, import and use the modular routes in server.ts:

import express from "express";
import v1 from "./routes/v1";

const app = express();

app.use("/v1", v1);

app.listen(3001, () => {
console.log("Server running on port 3001");
});

This ensures that all routes under /v1 are correctly registered.


Step 5: Testing the Routes

Start your server with:

npm run dev

Then, test your API using Postman or an HTTP client:

EndpointMethodResponse
/v1/tasksGET[] (empty array)
/v1/tasks/1GET{ id: 1, name: "Task 1" }
/v1/projectsGET[] (empty array)
/v1/projects/1GET{ id: 1, name: "Project 1" }
/v1/projects/1/tasksGET[] (empty array)

Conclusion

That’s a wrap on Express.js modular routing! By structuring routes properly, we:

✔ Kept code clean and organized
✔ Made it easier to scale the app
✔ Separated concerns for better maintainability

Now you can apply modular routing to your Express.js projects and build scalable APIs with ease!

Share this article

Similar Posts