Step 1: Create the Student Module Structure
First, create the folder structure for the Student
module.
express-backend-boilerplate/
│
├── src/
│ ├── config/
│ │ └── ormconfig.js
│ ├── index.js
│ └── modules/
│ └── student/
│ ├── controllers/
│ │ └── student.controller.js
│ ├── entities/
│ │ └── student.entity.js
│ ├── routes/
│ │ └── student.routes.js
│ ├── services/
│ │ └── student.service.js
│ └── studentModule.js
└── package.json
Step 2: Define the Student Entity
In student.entity.js
, define the Student entity using TypeORM.
// modules/student/entities/student.entity.js
const { EntitySchema } = require('typeorm');
module.exports = new EntitySchema({
name: 'Student',
tableName: 'students',
columns: {
id: {
type: 'int',
primary: true,
generated: true,
},
name: {
type: 'varchar',
nullable: false,
},
age: {
type: 'int',
nullable: false,
},
grade: {
type: 'varchar',
nullable: false,
},
createdAt: {
type: 'timestamp',
createDate: true,
},
updatedAt: {
type: 'timestamp',
updateDate: true,
},
},
});
Step 3 : Define the Student Service
const { AppDataSource } = require('../../../index');
const Student = require('../entities/student.entity');
/**
* @function formatStudentResponse
* @description Formats the student data to ensure consistent field names across all responses.
* @param {object} student - The student object to format.
* @returns {object} - The formatted student object.
*/
const formatStudentResponse = (student) => {
if (!student) return null;
return {
id: student.id,
name: student.name,
age: student.age,
grade: student.grade,
createdAt: student.createdAt,
updatedAt: student.updatedAt
};
};
const createStudent = async (data) => {
const entityManager = AppDataSource.getRepository(Student);
const student = entityManager.create(data);
const savedStudent = await entityManager.save(student);
return formatStudentResponse(savedStudent); // Format the response
};
const findStudentById = async (id) => {
const entityManager = AppDataSource.getRepository(Student);
const student = await entityManager.findOneBy({ id });
return formatStudentResponse(student); // Format the response
};
const updateStudent = async (id, data) => {
const entityManager = AppDataSource.getRepository(Student);
const student = await findStudentById(id);
if (!student) return null;
Object.assign(student, data);
const updatedStudent = await entityManager.save(student);
return formatStudentResponse(updatedStudent); // Format the response
};
const deleteStudent = async (id) => {
const entityManager = AppDataSource.getRepository(Student);
const result = await entityManager.delete(id);
return result.affected;
};
const getAllStudents = async () => {
const entityManager = AppDataSource.getRepository(Student);
const students = await entityManager.find();
return students.map(formatStudentResponse); // Format each student in the array
};
// Exporting the service functions to be used in controllers
module.exports = {
createStudent,
findStudentById,
updateStudent,
deleteStudent,
getAllStudents,
};
Step 4: Define the Student Controller
const studentService = require('../services/student.service');
/**
* @function createStudent
* @description Creates a new student.
* @param {object} req - Request object.
* @param {object} res - Response object.
*/
const createStudent = async (req, res) => {
try {
const student = await studentService.createStudent(req.body);
res.status(201).json(student);
} catch (error) {
res.status(500).json({ message: 'Failed to create student', error: error.message });
}
};
/**
* @function getStudentById
* @description Retrieves a student by ID.
* @param {object} req - Request object.
* @param {object} res - Response object.
*/
const getStudentById = async (req, res) => {
try {
const student = await studentService.findStudentById(req.params.id);
if (!student) {
return res.status(404).json({ message: 'Student not found' });
}
res.status(200).json(student);
} catch (error) {
res.status(500).json({ message: 'Failed to retrieve student', error: error.message });
}
};
/**
* @function updateStudent
* @description Updates a student by ID.
* @param {object} req - Request object.
* @param {object} res - Response object.
*/
const updateStudent = async (req, res) => {
try {
const student = await studentService.updateStudent(req.params.id, req.body);
if (!student) {
return res.status(404).json({ message: 'Student not found' });
}
res.status(200).json(student);
} catch (error) {
res.status(500).json({ message: 'Failed to update student', error: error.message });
}
};
/**
* @function deleteStudent
* @description Deletes a student by ID.
* @param {object} req - Request object.
* @param {object} res - Response object.
*/
const deleteStudent = async (req, res) => {
try {
const result = await studentService.deleteStudent(req.params.id);
if (result === 0) {
return res.status(404).json({ message: 'Student not found' });
}
res.status(204).send();
} catch (error) {
res.status(500).json({ message: 'Failed to delete student', error: error.message });
}
};
/**
* @function getAllStudents
* @description Controller function to handle the request for retrieving all students.
* @param {object} req - The request object.
* @param {object} res - The response object.
* @returns {Promise<void>}
*/
const getAllStudents = async (req, res) => {
try {
const students = await studentService.getAllStudents();
if (!students) {
return res.status(404).json({ message: 'No students found' });
}
res.status(200).json(students);
} catch (error) {
console.error('Error details:', error); // Log error details
res.status(500).json({
message: 'Internal server error',
error: error.message || 'An unexpected error occurred' // Include error message
});
}
};
module.exports = {
createStudent,
getStudentById,
updateStudent,
deleteStudent,
getAllStudents,
};
modules/student/routes/student.routes.js
This file defines the routes for the student module.
const express = require('express');
const router = express.Router();
const studentController = require('../controllers/student.controller');
// Define routes with corresponding controller methods
router.get('/students', studentController.getAllStudents);
router.post('/students', studentController.createStudent); // Create a new student
router.get('/students/:id', studentController.getStudentById); // Get student by ID
router.put('/students/:id', studentController.updateStudent); // Update student by ID
router.delete('/students/:id', studentController.deleteStudent); // Delete student by ID
module.exports = router;
studentModule.js
const studentRoutes = require('./routes/student.routes');
const studentService = require('./services/student.service');
const studentController = require('./controllers/student.controller');
// Exporting the components of the Student module
module.exports = {
studentRoutes,
studentService,
studentController,
};
Integration into index.js
Update src/index.js
to include the initialization of the studentModule.js
.
Updated src/index.js
require('dotenv').config(); // Load environment variables
require('reflect-metadata'); // Required by TypeORM for decorators
const express = require('express');
const { DataSource } = require('typeorm');
const ormConfig = require('./config/ormconfig');
// Initialize TypeORM DataSource
const AppDataSource = new DataSource(ormConfig);
const initializeApp = async () => {
// Initialize DataSource
await AppDataSource.initialize();
console.log('Database connected successfully!');
// Initialize Express app
const app = express();
// Configure middlewares
app.use(express.json());
// Import and use Student module
const { studentRoutes } = require('./modules/student/studentModule');
// Use the student routes in the application
app.use('/api', studentRoutes);
// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
};
initializeApp().catch((error) => {
console.error('Error initializing app:', error);
});
// Export the AppDataSource for TypeORM CLI usage
module.exports = {
AppDataSource,
};
Generate Migration
To generate a migration file with TypeORM, use the migration:generate
command. This command will create a new migration file based on changes detected in your entities.
Assuming your ormconfig.js
is correctly exporting the configuration, and the AppDataSource
is properly initialized in src/index.js
, use the following command:
npx typeorm migration:generate -d src/index.js src/migrations/initial-migration --outputJs
move generate migration js file in migration folder then next step
3. Run Migration
To run the migrations and apply them to the database, use the migration:run
command:
npx typeorm migration:run -d src/index.js