Personal Blogging Platform: Mastering Database Architecture and CRUD Operations
Last Updated :
23 Jul, 2025
A personal blogging platform is an excellent project to explore the fundamentals of database design and management, along with its integration into scalable web applications. It provides the foundational infrastructure to handle blog-related operations such as creating, reading, updating, and deleting articles.
In this project ensures scalability, maintainability, and efficiency by implementing a robust database and using the MVC (Model-View-Controller) architecture. This article covers the project’s structure, features, database design, and complete implementation code for creating a personal blogging platform.
Blogging Platform Features
We have implemented the following features in this project.
CRUD Operations on Articles:
- Create: Add new blog posts.
- Read: Fetch a list of articles or a specific article by ID.
- Update: Modify existing articles.
- Delete: Remove articles by ID.
Filter Articles: Filter by tags or publishing date.
User Management: Manage authors for articles.
Additional Features:
- Commenting system.
- Like system for articles.
Architecture of Blogging Platform
The architecture of the Blogging Platform API is based on the MVC (Model-View-Controller) design pattern, ensuring clear separation of concerns and scalability.
Architecture Blogging PlatformHere’s a breakdown of the architecture:
Client Layer
- Represents the users interacting with the system via tools like Postman, web browsers, or frontend applications.
- Sends HTTP requests to the backend server using RESTful methods (GET, POST, PUT, DELETE).
Server Layer
- Routes: Define API endpoints that map user requests to specific controller functions.
- Controllers: Handle the business logic, process user requests, and invoke models for database operations.
- Middleware: Handles JSON parsing, error handling, and other pre-processing tasks for incoming requests.
- Models: Act as the interface to the database, executing SQL queries for CRUD operations.
Database Layer
- Relational Database: Stores persistent data in normalized tables (users, articles, comments, likes).
- Relationships:
- users → articles (One-to-Many): A user can create multiple articles.
- articles → comments (One-to-Many): An article can have multiple comments.
- articles → likes (One-to-Many): An article can have multiple likes.
Data Flow
- The client sends a request to a route.
- The route invokes the corresponding controller function.
- The controller processes the request and interacts with the model to fetch or manipulate data in the database.
- The database returns results to the model, which then passes them to the controller.
- The controller sends the final response back to the client.
- This architecture ensures modularity, maintainability, and scalability, making it suitable for real-world applications.
Database Design - Blogging Platform
CREATE DATABASE personal_blog;
USE personal_blog;
-- Users Table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Articles Table
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
tags VARCHAR(255),
published_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Comments Table
CREATE TABLE comments (
id INT AUTO_INCREMENT PRIMARY KEY,
article_id INT NOT NULL,
user_id INT NOT NULL,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Likes Table
CREATE TABLE likes (
id INT AUTO_INCREMENT PRIMARY KEY,
article_id INT NOT NULL,
user_id INT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Output:
Database Design - Blogging PlatformProject Structure - Blogging Platform
The project follows the MVC (Model-View-Controller) architecture, which separates the application logic into distinct layers for better organization and maintainability.
- controllers/: Contains the logic for handling requests and responses.
- models/: Defines how data is structured and includes methods to interact with the database.
- routes/: Manages the API endpoints and connects them to corresponding controllers.
- config/: Handles database connection settings.
- app.js: The main entry point of the application.
Blogging Platform - Code Implementation
Here we will explain all the codeand structures of the projects in detail in step wise.
1. Database Configuration
This step establishes the connection between the application and the MySQL database. The configuration ensures that all database queries are routed through a pool of connections, optimizing performance and handling multiple requests efficiently. By creating a dbConfig.js file, we centralize the database settings, making it easier to manage and update.
The configuration integrates with the project by exporting a promise-based connection pool, which is used by the models (like articleModel.js) to execute SQL queries. This approach keeps the database logic separate from the rest of the application, adhering to the MVC architecture and enhancing maintainability.
config/dbConfig.js
config/dbConfig.js
// Importing required modules for database connection
const mysql = require('mysql2');
require('dotenv').config(); // Load environment variables from .env file
// Creating a connection pool for efficient database querying
const pool = mysql.createPool({
host: process.env.DB_HOST, // Database host
user: process.env.DB_USER, // Database user
password: process.env.DB_PASSWORD, // Database password
database: process.env.DB_NAME, // Database name
});
// Exporting a promise-based pool to allow async/await syntax in queries
module.exports = pool.promise();
2. Article Model
The Article Model (models/articleModel.js) serves as the intermediary between the database and the application logic. It contains methods that correspond directly to specific CRUD operations required by the API endpoints:
- getAllArticles(filters): Fetches all articles from the database. It supports filtering by tags or publishing date using query parameters.
- getArticleById(id): Retrieves a single article by its ID. This method is used when a user requests detailed information about a specific article.
- createArticle(data): Inserts a new article into the database. The data parameter includes the article’s title, content, and tags.
- updateArticle(id, data): Updates an existing article in the database. The id identifies the article to be updated, and data contains the new values for the title, content, or tags.
- deleteArticle(id): Deletes an article from the database based on its ID.
Each method integrates with the database configuration (dbConfig.js) to execute SQL queries. These methods ensure that the model handles all interactions with the articles table, encapsulating database logic and maintaining separation of concerns within the MVC architecture.
models/articleModel.js
models/articleModel.js
// Article Model: Handles all interactions with the 'articles' table
class Article {
// Retrieve all articles with optional filters for tag and date
static async getAllArticles(filters = {}) {
const { tag, date } = filters;
let query = 'SELECT * FROM articles WHERE 1=1'; // Base query
const params = [];
if (tag) {
query += ' AND FIND_IN_SET(?, tags)'; // Add condition for tag filter
params.push(tag);
}
if (date) {
query += ' AND DATE(published_at) = ?'; // Add condition for date filter
params.push(date);
}
// Execute the query and return the result
const [rows] = await db.execute(query, params);
return rows;
}
// Fetch a specific article by its ID
static async getArticleById(id) {
const [rows] = await db.execute('SELECT * FROM articles WHERE id = ?', [id]);
return rows[0]; // Return the first row, or undefined if not found
}
// Insert a new article into the database
static async createArticle(data) {
const { title, content, tags } = data;
const [result] = await db.execute(
'INSERT INTO articles (title, content, tags) VALUES (?, ?, ?)',
[title, content, tags]
);
return result.insertId; // Return the ID of the newly created article
}
// Update an existing article by its ID
static async updateArticle(id, data) {
const { title, content, tags } = data;
await db.execute(
'UPDATE articles SET title = ?, content = ?, tags = ? WHERE id = ?',
[title, content, tags, id]
);
}
// Delete an article by its ID
static async deleteArticle(id) {
await db.execute('DELETE FROM articles WHERE id = ?', [id]);
}
}
module.exports = Article;
3. Article Controller
The Article Controller (controllers/articleController.js) handles the logic for processing incoming requests related to articles. It uses methods from the Article Model to interact with the database and sends appropriate responses back to the client:
- getAllArticles(req, res): Retrieves all articles from the database. It extracts query parameters from req.query to filter articles by tags or publishing date. The response contains the filtered list of articles or all articles if no filters are applied.
- getArticleById(req, res): Fetches a specific article by its ID from req.params.id. If the article does not exist, it responds with a 404 error.
- createArticle(req, res): Adds a new article to the database using data from req.body. On success, it responds with the ID of the newly created article and a success message.
- updateArticle(req, res): Updates an existing article based on its ID (req.params.id) and new data (req.body). It responds with a success message after the update.
- deleteArticle(req, res): Deletes an article by its ID (req.params.id). It responds with a success message after the deletion.
These methods ensure the controller acts as a bridge between the client requests and database operations, maintaining the separation of concerns in the MVC architecture.
controllers/articleController.js
controllers/articleController.js
// Importing the Article model for database operations
const Article = require('../models/articleModel');
// Controller to handle fetching all articles
exports.getAllArticles = async (req, res) => {
try {
const filters = req.query; // Extract filters from the query string
const articles = await Article.getAllArticles(filters);
res.json(articles); // Respond with the list of articles
} catch (error) {
res.status(500).json({ error: 'Failed to fetch articles' });
}
};
// Controller to fetch a single article by ID
exports.getArticleById = async (req, res) => {
try {
const article = await Article.getArticleById(req.params.id);
if (!article) return res.status(404).json({ error: 'Article not found' });
res.json(article);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch article' });
}
};
// Controller to create a new article
exports.createArticle = async (req, res) => {
try {
const id = await Article.createArticle(req.body); // Create article in database
res.status(201).json({ message: 'Article created', id });
} catch (error) {
res.status(500).json({ error: 'Failed to create article' });
}
};
// Controller to update an existing article by ID
exports.updateArticle = async (req, res) => {
try {
await Article.updateArticle(req.params.id, req.body); // Update the article
res.json({ message: 'Article updated' });
} catch (error) {
res.status(500).json({ error: 'Failed to update article' });
}
};
// Controller to delete an article by ID
exports.deleteArticle = async (req, res) => {
try {
await Article.deleteArticle(req.params.id); // Delete the article
res.json({ message: 'Article deleted' });
} catch (error) {
res.status(500).json({ error: 'Failed to delete article' });
}
};
4. Routes
The Routes (routes/articleRoutes.js) define the API endpoints and link them to the appropriate controller methods. This modular approach simplifies route management and ensures clear separation of concerns:
- GET /: Calls articleController.getAllArticles to retrieve all articles, optionally filtered by query parameters (e.g., tags, publishing date).
- GET /:id: Calls articleController.getArticleById to fetch a specific article by its ID.
- POST /: Calls articleController.createArticle to add a new article. The article details are passed in the request body.
- PUT /:id: Calls articleController.updateArticle to modify an existing article by its ID. Updated data is passed in the request body.
- DELETE /:id: Calls articleController.deleteArticle to remove an article by its ID.
The Routes module centralizes endpoint definitions, linking them to the corresponding controller methods for a clean and scalable API structure.
routes/articleRoutes.js
routes/articleRoutes.js
// Importing the required modules
const express = require('express');
const articleController = require('../controllers/articleController');
const router = express.Router(); // Create a router instance
// Define the routes and map them to controller methods
router.get('/', articleController.getAllArticles); // Fetch all articles
router.get('/:id', articleController.getArticleById); // Fetch a single article by ID
router.post('/', articleController.createArticle); // Create a new article
router.put('/:id', articleController.updateArticle); // Update an article by ID
router.delete('/:id', articleController.deleteArticle); // Delete an article by ID
module.exports = router; // Export the router for use in app.js
5. Application Entry Point
This step involves setting up the entry point of the application, which ties together all the components of the project. The app.js file serves as the backbone of the API, handling middleware, routing, and server initialization.
This setup is crucial for creating a functional and scalable application that can handle requests and responses seamlessly.
app.js
app.js
const express = require('express');
const bodyParser = require('body-parser');
const articleRoutes = require('./routes/articleRoutes'); // Import article routes
const app = express();
// Use body-parser middleware to parse JSON requests
app.use(bodyParser.json());
// Mount the article routes under the /api/articles path
app.use('/api/articles', articleRoutes);
// Start the server and listen on the specified port
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Conclusion
This project, the Personal Blogging Platform API, serves as an excellent example of how to design and implement a RESTful API using Node.js and MySQL. By following the MVC (Model-View-Controller) architecture, it ensures clear separation of concerns, modularity, and scalability. The project introduces real-world database concepts like relationships, foreign keys, and SQL operations, making it a great hands-on exercise for anyone looking to strengthen their understanding of backend development and database integration.
Similar Reads
SQL Tutorial Structured Query Language (SQL) is the standard language used to interact with relational databases. Mainly used to manage data. Whether you want to create, delete, update or read data, SQL provides the structure and commands to perform these operations. Widely supported across various database syst
8 min read
Basics
What is SQL?Structured Query Language (SQL) is the standard language used to interact with relational databases. Allows users to store, retrieve, update, and manage data efficiently through simple commands. Known for its user-friendly syntax and powerful capabilities, SQL is widely used across industries.How Do
6 min read
SQL Data TypesSQL data types define the kind of data a column can store, dictating how the database manages and interacts with the data. Each data type in SQL specifies a set of allowed values, as well as the operations that can be performed on the values.SQL data types are broadly categorized into several groups
4 min read
SQL OperatorsSQL operators are symbols or keywords used to perform operations on data in SQL queries. These operations can include mathematical calculations, data comparisons, logical manipulations, other data-processing tasks. Operators help in filtering, calculating, and updating data in databases, making them
5 min read
SQL Commands | DDL, DQL, DML, DCL and TCL CommandsSQL commands are the fundamental building blocks for communicating with a database management system (DBMS). It is used to interact with the database with some operations. It is also used to perform specific tasks, functions, and queries of data. SQL can perform various tasks like creating a table,
7 min read
SQL Database OperationsSQL databases or relational databases are widely used for storing, managing and organizing structured data in a tabular format. These databases store data in tables consisting of rows and columns. SQL is the standard programming language used to interact with these databases. It enables users to cre
3 min read
SQL CREATE TABLEIn SQL, creating a table is one of the most essential tasks for structuring your database. The CREATE TABLE statement defines the structure of the database table, specifying column names, data types, and constraints such as PRIMARY KEY, NOT NULL, and CHECK. Mastering this statement is fundamental to
5 min read
Queries & Operations
SQL SELECT QueryThe SQL SELECT query is one of the most frequently used commands to retrieve data from a database. It allows users to access and extract specific records based on defined conditions, making it an essential tool for data management and analysis. In this article, we will learn about SQL SELECT stateme
4 min read
SQL INSERT INTO StatementThe SQL INSERT INTO statement is one of the most essential commands for adding new data into a database table. Whether you are working with customer records, product details or user information, understanding and mastering this command is important for effective database management. How SQL INSERT I
6 min read
SQL UPDATE StatementIn SQL, the UPDATE statement is used to modify existing records in a table. Whether you are updating a single record or multiple records at once, SQL provides the necessary functionality to make these changes. Whether you are working with a small dataset or handling large-scale databases, the UPDATE
6 min read
SQL DELETE StatementThe SQL DELETE statement is an essential command in SQL used to remove one or more rows from a database table. Unlike the DROP statement, which removes the entire table, the DELETE statement removes data (rows) from the table retaining only the table structure, constraints, and schema. Whether you n
4 min read
SQL | WHERE ClauseThe SQL WHERE clause allows filtering of records in queries. Whether you are retrieving data, updating records, or deleting entries from a database, the WHERE clause plays an important role in defining which rows will be affected by the query. Without WHERE clause, SQL queries would return all rows
4 min read
SQL | AliasesIn SQL, aliases are temporary names assigned to columns or tables for the duration of a query. They make the query more readable, especially when dealing with complex queries or large datasets. Aliases help simplify long column names, improve query clarity, and are particularly useful in queries inv
4 min read
SQL Joins & Functions
SQL Joins (Inner, Left, Right and Full Join)SQL joins are fundamental tools for combining data from multiple tables in relational databases. For example, consider two tables where one table (say Student) has student information with id as a key and other table (say Marks) has information about marks of every student id. Now to display the mar
4 min read
SQL CROSS JOINIn SQL, the CROSS JOIN is a unique join operation that returns the Cartesian product of two or more tables. This means it matches each row from the left table with every row from the right table, resulting in a combination of all possible pairs of records. In this article, we will learn the CROSS JO
3 min read
SQL | Date Functions (Set-1)SQL Date Functions are essential for managing and manipulating date and time values in SQL databases. They provide tools to perform operations such as calculating date differences, retrieving current dates and times and formatting dates. From tracking sales trends to calculating project deadlines, w
5 min read
SQL | String functionsSQL String Functions are powerful tools that allow us to manipulate, format, and extract specific parts of text data in our database. These functions are essential for tasks like cleaning up data, comparing strings, and combining text fields. Whether we're working with names, addresses, or any form
7 min read
Data Constraints & Aggregate Functions
SQL NOT NULL ConstraintIn SQL, constraints are used to enforce rules on data, ensuring the accuracy, consistency, and integrity of the data stored in a database. One of the most commonly used constraints is the NOT NULL constraint, which ensures that a column cannot have NULL values. This is important for maintaining data
3 min read
SQL PRIMARY KEY ConstraintThe PRIMARY KEY constraint in SQL is one of the most important constraints used to ensure data integrity in a database table. A primary key uniquely identifies each record in a table, preventing duplicate or NULL values in the specified column(s). Understanding how to properly implement and use the
5 min read
SQL Count() FunctionIn the world of SQL, data analysis often requires us to get counts of rows or unique values. The COUNT() function is a powerful tool that helps us perform this task. Whether we are counting all rows in a table, counting rows based on a specific condition, or even counting unique values, the COUNT()
7 min read
SQL SUM() FunctionThe SUM() function in SQL is one of the most commonly used aggregate functions. It allows us to calculate the total sum of a numeric column, making it essential for reporting and data analysis tasks. Whether we're working with sales data, financial figures, or any other numeric information, the SUM(
5 min read
SQL MAX() FunctionThe MAX() function in SQL is a powerful aggregate function used to retrieve the maximum (highest) value from a specified column in a table. It is commonly employed for analyzing data to identify the largest numeric value, the latest date, or other maximum values in various datasets. The MAX() functi
4 min read
AVG() Function in SQLSQL is an RDBMS system in which SQL functions become very essential to provide us with primary data insights. One of the most important functions is called AVG() and is particularly useful for the calculation of averages within datasets. In this, we will learn about the AVG() function, and its synta
4 min read
Advanced SQL Topics
SQL SubqueryA subquery in SQL is a query nested within another SQL query. It allows you to perform complex filtering, aggregation, and data manipulation by using the result of one query inside another. Subqueries are often found in the WHERE, HAVING, or FROM clauses and are supported in SELECT, INSERT, UPDATE,
5 min read
Window Functions in SQLSQL window functions are essential for advanced data analysis and database management. It is a type of function that allows us to perform calculations across a specific set of rows related to the current row. These calculations happen within a defined window of data and they are particularly useful
6 min read
SQL Stored ProceduresStored procedures are precompiled SQL statements that are stored in the database and can be executed as a single unit. SQL Stored Procedures are a powerful feature in database management systems (DBMS) that allow developers to encapsulate SQL code and business logic. When executed, they can accept i
7 min read
SQL TriggersA trigger is a stored procedure in adatabase that automatically invokes whenever a special event in the database occurs. By using SQL triggers, developers can automate tasks, ensure data consistency, and keep accurate records of database activities. For example, a trigger can be invoked when a row i
7 min read
SQL Performance TuningSQL performance tuning is an essential aspect of database management that helps improve the efficiency of SQL queries and ensures that database systems run smoothly. Properly tuned queries execute faster, reducing response times and minimizing the load on the serverIn this article, we'll discuss var
8 min read
SQL TRANSACTIONSSQL transactions are essential for ensuring data integrity and consistency in relational databases. Transactions allow for a group of SQL operations to be executed as a single unit, ensuring that either all the operations succeed or none of them do. Transactions allow us to group SQL operations into
8 min read
Database Design & Security
Introduction of ER ModelThe Entity-Relationship Model (ER Model) is a conceptual model for designing a databases. This model represents the logical structure of a database, including entities, their attributes and relationships between them. Entity: An objects that is stored as data such as Student, Course or Company.Attri
10 min read
Introduction to Database NormalizationNormalization is an important process in database design that helps improve the database's efficiency, consistency, and accuracy. It makes it easier to manage and maintain the data and ensures that the database is adaptable to changing business needs.Database normalization is the process of organizi
6 min read
SQL InjectionSQL Injection is a security flaw in web applications where attackers insert harmful SQL code through user inputs. This can allow them to access sensitive data, change database contents or even take control of the system. It's important to know about SQL Injection to keep web applications secure.In t
7 min read
SQL Data EncryptionIn todayâs digital era, data security is more critical than ever, especially for organizations storing the personal details of their customers in their database. SQL Data Encryption aims to safeguard unauthorized access to data, ensuring that even if a breach occurs, the information remains unreadab
5 min read
SQL BackupIn SQL Server, a backup, or data backup is a copy of computer data that is created and stored in a different location so that it can be used to recover the original in the event of a data loss. To create a full database backup, the below methods could be used : 1. Using the SQL Server Management Stu
4 min read
What is Object-Relational Mapping (ORM) in DBMS?Object-relational mapping (ORM) is a key concept in the field of Database Management Systems (DBMS), addressing the bridge between the object-oriented programming approach and relational databases. ORM is critical in data interaction simplification, code optimization, and smooth blending of applicat
7 min read