Refactoring Project

In a typical beginner setup, we often place all logic (server configuration, routes, database connection) inside a single file like index.ts.

But as your project grows, this becomes:

  • ๐Ÿงน Messy

  • ๐Ÿ˜ฐ Hard to manage

  • ๐Ÿ‘Ž Against best practices like Single Responsibility Principle

๐Ÿงจ Current Problem: Everything in index.ts

sh
// index.ts
import * as express from ‘express’;
import * as mongoose from ‘mongoose’;
import { getEnvironmentVariables } from ‘./environments/env’;
const app = express();
app.listen(5000, () => {
console.log(‘Server is running’);
});
// DB Connection Logic
const DB_URI = getEnvironmentVariables().db_url;
mongoose.connect(DB_URI, { dbName: ‘test’ })
.then(() => console.log(‘โœ… MongoDB connected’))
.catch(err => console.error(‘โŒ Mongo Error:’, err.message));
// Route Handlers
app.get(‘/login’, (req, res) => res.send(‘Login logic’));
app.get(‘/test’, (req, res) => res.send(‘Test route’));

This is fine for learning, but not scalable or clean.

โœ… Goal: A Clean, Modular Project Structure

We’ll split responsibilities into separate files and folders:

  • server.ts โ†’ App logic & server startup

  • routes/ โ†’ Route definitions

  • controllers/ โ†’ Handle request logic

  • index.ts โ†’ Entry point

 

๐Ÿ›  Step-by-Step Refactoring

 

๐Ÿ“ 1. Create server.ts

Handles:

  • MongoDB connection

  • Route registration

sh
// server.ts
import * as express from ‘express’;
import * as mongoose from ‘mongoose’;
import { getEnvironmentVariables } from ‘./environments/env’;
import UserRouter from ‘./routes/UserRouter’;
export class Server {
public app: express.Application = express();
constructor() {
this.setConfigurations();
this.setRoutes();
}
setConfigurations() {
this.connectMongoDb();
}
connectMongoDb() {
const DB_URI = getEnvironmentVariables().db_url;
mongoose.connect(DB_URI, { dbName: ‘test’ })
.then(() => console.log(‘โœ… MongoDB connected successfully’))
.catch(err => {
console.error(‘โŒ MongoDB connection error:’, err.message);
process.exit(1);
});
mongoose.connection.on(‘connected’, () => {
console.log(‘Mongoose connected to DB’);
});
mongoose.connection.on(‘error’, (err) => {
console.log(‘Mongoose connection error:’, err);
});
mongoose.connection.on(‘disconnected’, () => {
console.log(‘Mongoose disconnected’);
});
}
setRoutes() {
this.app.use(‘/api/user’, UserRouter); // all user-related routes
}
}

๐Ÿ“ 2. Create routes/UserRouter.ts

Handles:

  • Route paths (/login, /signup)

  • Forwards logic to controllers

sh
// routes/UserRouter.ts
import { Router } from ‘express’;
import { UserController } from ‘../controllers/UserController’;
export class UserRouter {
public router: Router;
constructor() {
this.router = Router();
this.getRoutes();
this.postRoutes();
this.patchRoutes();
this.deleteRoutes();
}
getRoutes() {
this.router.get(‘/login’, UserController.login);
}
postRoutes() {}
patchRoutes() {}
deleteRoutes() {}
}
export default new UserRouter().router;

๐Ÿ“ 3. Create controllers/UserController.ts

Handles:

  • Request โ†’ Response logic (business logic)

sh
// controllers/UserController.ts
export class UserController {
static login(req, res) {
res.send(‘We are here to login’);
}
}

๐ŸŸข 4. Update index.ts

Entry point for your project. Simple and clean.

sh
// index.ts
import { Server } from ‘./server’;
const server = new Server().app;
const port = 5000;
server.listen(port, () => {
console.log(`๐Ÿš€ Server is running on port ${port}`);
});

๐Ÿ“ฆ Final Project Structure

sh
nodejs-project/
โ”œโ”€โ”€ node_modules/
โ”œโ”€โ”€ src/
โ”‚ โ”œโ”€โ”€ controllers/
โ”‚ โ”‚ โ””โ”€โ”€ UserController.ts
โ”‚ โ”œโ”€โ”€ environments/
โ”‚ โ”‚ โ”œโ”€โ”€ dev.env.ts
โ”‚ โ”‚ โ”œโ”€โ”€ env.ts
โ”‚ โ”‚ โ””โ”€โ”€ prod.env.ts
โ”‚ โ”œโ”€โ”€ routes/
โ”‚ โ”‚ โ””โ”€โ”€ UserRouter.ts
โ”‚ โ”œโ”€โ”€ server.ts
โ”‚ โ””โ”€โ”€ index.ts
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ package-lock.json
โ””โ”€โ”€ tsconfig.json

๐Ÿ” Testing Your Refactored API

Use Postman or browser:

GET Request to:

sh
http://localhost:5000/api/user/login

โœ… Output:

sh
We are here to login

Postman testing of user login nodereactjs

๐Ÿง  Visual Flow Diagram

sh
index.ts
โ†“
server.ts โ†’ configures Express + MongoDB
โ†“
routes/UserRouter.ts โ†’ defines /login route
โ†“
controllers/UserController.ts โ†’ handles actual login logic

โœจ Benefits of This Structure

โœ… Follows Single Responsibility Principle
โœ… Clean separation of concerns
โœ… Easy to scale with new features (like auth, admin, product, etc.)
โœ… Understandable and maintainable for any developer

Scroll to Top