Sequelize Folder Structure
Introduction
When building a Node.js application using Sequelize (an ORM for interacting with SQL databases), it's common to organize the code into a structured folder system that reflects the different layers of the application. Here's a common folder structure for Sequelize CRUD (Create, Read, Update, Delete) operations,
i) /models
ii) /controllersiii) /routes
iv) /config
v) /app.js or /server.js/models
Contains the Sequelize models, which define the structure of your database tables and the relationships between them.Each model file typically represents a database table.
A common pattern is to have a
index.jsfile in this folder to dynamically load and initialize all models./models ├── user.js # Sequelize model for 'User' ├── post.js # Sequelize model for 'Post' └── index.js # Initializes and exports all models// user.js (Model Example) module.exports = (sequelize, DataTypes) => { const User = sequelize.define('User', { name: { type: DataTypes.STRING, allowNull: false }, email: { type: DataTypes.STRING, allowNull: false, unique: true } }); return User; };// index.js (Model Initialization) const fs = require('fs'); const path = require('path'); const Sequelize = require('sequelize'); const basename = path.basename(__filename); const env = process.env.NODE_ENV || 'development'; const config = require(__dirname + '/../config/config.json')[env]; const db = {}; const sequelize = new Sequelize(config.database, config.username, config.password, config); fs.readdirSync(__dirname) .filter(file => { return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); }) .forEach(file => { const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); db[model.name] = model; }); Object.keys(db).forEach(modelName => { if (db[modelName].associate) { db[modelName].associate(db); } }); db.sequelize = sequelize; db.Sequelize = Sequelize; module.exports = db;/controllers
Contains logic that responds to incoming requests and interacts with the models. This is where the CRUD operations (Create, Read, Update, Delete) happen.
Each controller typically maps to a model and defines the methods for handling the operations on the corresponding table (e.g.,
UserControllerfor theUsermodel)./controllers ├── userController.js └── postController.js// userController.js (CRUD Example) const { User } = require('../models'); // Create a new User exports.createUser = async (req, res) => { try { const user = await User.create(req.body); res.status(201).json(user); } catch (error) { res.status(400).json({ error: error.message }); } }; // Get all Users exports.getAllUsers = async (req, res) => { try { const users = await User.findAll(); res.status(200).json(users); } catch (error) { res.status(500).json({ error: error.message }); } }; // Update a User exports.updateUser = async (req, res) => { try { const { id } = req.params; const user = await User.findByPk(id); if (!user) { return res.status(404).json({ error: 'User not found' }); } await user.update(req.body); res.status(200).json(user); } catch (error) { res.status(400).json({ error: error.message }); } }; // Delete a User exports.deleteUser = async (req, res) => { try { const { id } = req.params; const user = await User.findByPk(id); if (!user) { return res.status(404).json({ error: 'User not found' }); } await user.destroy(); res.status(204).json(); } catch (error) { res.status(500).json({ error: error.message }); } };/routes
This folder contains the route definitions. Each route typically maps to a controller method for handling a specific HTTP request (GET, POST, PUT, DELETE)./routes ├── userRoutes.js └── postRoutes.js// userRoutes.js (Route Example) const express = require('express'); const router = express.Router(); const userController = require('../controllers/userController'); // Routes for User CRUD operations router.post('/users', userController.createUser); router.get('/users', userController.getAllUsers); router.put('/users/:id', userController.updateUser); router.delete('/users/:id', userController.deleteUser); module.exports = router;/config
This folder contains configuration files, such as database configurations for different environments (development, production, testing).
/config └── config.json# config.json (Example) { "development": { "username": "root", "password": null, "database": "database_dev", "host": "127.0.0.1", "dialect": "mysql" }, "test": { "username": "root", "password": null, "database": "database_test", "host": "127.0.0.1", "dialect": "mysql" }, "production": { "username": "root", "password": null, "database": "database_prod", "host": "127.0.0.1", "dialect": "mysql" } }/app.js or /server.js
This file initializes the Express server, connects to the database, and loads the routes.
const express = require('express'); const app = express(); const db = require('./models'); const userRoutes = require('./routes/userRoutes'); app.use(express.json()); app.use('/api', userRoutes); db.sequelize.sync().then(() => { app.listen(3000, () => { console.log('Server is running on port 3000'); }); });Complete Folder Structure Example
/my-sequelize-app ├── /models ├── /controllers ├── /routes ├── /config ├── /migrations (optional) ├── /seeders (optional) ├── app.js └── package.jsonThis structure provides a clean separation of concerns, where models handle database interactions, controllers manage business logic, and routes define the API endpoints. This approach keeps the code modular, scalable, and easier to maintain.