ExpressJs

⌘K
  1. Home
  2. Docs
  3. ExpressJs
  4. Nodejs Moduler System
  5. Student Module

Student Module

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

How can we help?