Building a Full-Stack CRUD Application with Express.js, MySQL, and Sequelize
Introduction to MySQL and Sequelize ORM: A Complete Guide for Node.js Developers
In today's data-driven world, building robust database applications is essential for developers. MySQL remains one of the most popular relational database systems, and Sequelize provides an elegant Node.js ORM to interact with it. In this comprehensive tutorial, we'll build a complete CRUD (Create, Read, Update, Delete) application using Express.js, MySQL, and Sequelize from scratch.
Prerequisites
- Node.js and npm installed on your system
- MySQL installed and running
- Basic understanding of JavaScript and Express.js
- A cup of coffee (coding is always better with caffeine)
Let's dive into building our application!
Setting Up MySQL for Our Project
Before we start coding, you'll need MySQL installed and running on your system.
Step 1: Install MySQL
If you haven't installed MySQL yet, download it from the official website and follow the installation instructions for your operating system.
Step 2: Create a Database
Open your MySQL terminal or MySQL Workbench and run:
CREATE DATABASE crud_db;
That's it! Sequelize will handle creating our tables automatically.
Building Our Application Step by Step
Step 1: Initialize Your Node.js Project
Create a new directory and initialize a Node.js project:
mkdir sequelize-crud
cd sequelize-crud
npm init -y
Step 2: Install Required Dependencies
npm install express mysql2 sequelize dotenv
npm install --save-dev nodemon
Step 3: Create Environment Variables
Create a .env
file to store your database credentials:
DB_NAME=crud_db
DB_USER=root
DB_PASSWORD=1234Asdf?
DB_HOST=localhost
DB_DIALECT=mysql
PORT=3500
Step 4: Set Up Sequelize
Create a directory for configuration files:
mkdir config
Now let's create the Sequelize configuration file. This file will handle connecting to the MySQL database and setting up the Sequelize instance.
Create config/database.js
:
const { Sequelize } = require('sequelize');
require('dotenv').config();
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST,
dialect: process.env.DB_DIALECT,
logging: false,
}
);
const connectDB = async () => {
try {
await sequelize.authenticate();
console.log('Database connection has been established successfully.');
await sequelize.sync({ alter: true });
console.log('All models were synchronized successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
process.exit(1);
}
};
module.exports = { sequelize, connectDB };
Step 5: Define Models
Create a directory for models:
mkdir models
Create models/User.js
:
const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true,
},
},
age: {
type: DataTypes.INTEGER,
allowNull: true,
}
}, {
tableName: 'users',
timestamps: true,
});
module.exports = User;
Step 6: Create Controllers
Create a directory for controllers:
mkdir controllers
Create controllers/userController.js
:
const User = require('../models/user');
// Create a new user
exports.createUser = async (req, res) => {
try {
const { name, email, age } = req.body;
const user = await User.create({
name,
email,
age
});
res.status(201).json({
success: true,
data: user
});
} catch (error) {
res.status(400).json({
success: false,
error: error.message
});
}
};
// Get all users
exports.getAllUsers = async (req, res) => {
try {
const users = await User.findAll();
res.status(200).json({
success: true,
count: users.length,
data: users
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
};
// Get a single user by ID
exports.getUserById = async (req, res) => {
try {
const user = await User.findByPk(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
res.status(200).json({
success: true,
data: user
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
};
// Update a user
exports.updateUser = async (req, res) => {
try {
const user = await User.findByPk(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
const { name, email, age } = req.body;
await user.update({
name: name || user.name,
email: email || user.email,
age: age || user.age
});
res.status(200).json({
success: true,
data: user
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
};
// Delete a user
exports.deleteUser = async (req, res) => {
try {
const user = await User.findByPk(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
await user.destroy();
res.status(200).json({
success: true,
data: {}
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
};
Step 7: Set Up Routes
Create a directory for routes:
mkdir routes
Create routes/userRoutes.js
:
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
// Create a new user
router.post('/', userController.createUser);
// Get all users
router.get('/', userController.getAllUsers);
// Get a single user
router.get('/:id', userController.getUserById);
// Update a user
router.put('/:id', userController.updateUser);
// Delete a user
router.delete('/:id', userController.deleteUser);
module.exports = router;
Step 8: Create the Express Server
Create server.js
:
const express = require('express');
const { connectDB } = require('./config/database');
const userRoutes = require('./routes/userRoutes');
require('dotenv').config();
// Initialize Express app
const app = express();
// Connect to database
connectDB();
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Routes
app.use('/api/users', userRoutes);
// Home route
app.get('/', (req, res) => {
res.send('Welcome to User CRUD API with Express, MySQL, and Sequelize');
});
// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Step 9: Run the Application
Start the application using nodemon:
npx nodemon server.js
Your CRUD application is now up and running! You can use tools like Postman to test the API endpoints.
Folder Structure
Here's the final folder structure of our project:
sequelize-crud/
├── config/
│ └── database.js
├── controllers/
│ └── userController.js
├── models/
│ └── User.js
├── routes/
│ └── userRoutes.js
├── .env
├── package.json
├── server.js
Conclusion
In this tutorial, we built a full-stack CRUD application using Express.js, MySQL, and Sequelize. We covered setting up the project, defining models, creating controllers, and setting up routes. With this foundation, you can expand the application further by adding authentication, validation, and more features.
Don't forget to drop a like ❤️😉❤️
Happy coding!
Top comments (0)