A Node.js Express REST API backend for a blog platform with user authentication, role-based access control, and blog management.
git clone <repository-url>
cd blog-backendnpm installCreate a .env file in the root directory with the following variables:
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=blog_platform
PORT=5000Ensure MySQL is running on your system, then:
# Create the database and tables
mysql -u root -p < schema.sqlOr the database will be automatically initialized on first application run.
npm install --save-dev nodemon| Variable | Description | Default |
|---|---|---|
DB_HOST |
MySQL database host | localhost |
DB_USER |
MySQL database user | root |
DB_PASSWORD |
MySQL database password | - |
DB_NAME |
MySQL database name | blog_platform |
PORT |
Server port | 5000 |
npm run devnpm startThe server will start on http://localhost:5000
- Docker and Docker Compose installed on your system
-
Ensure the
.envfile ordocker-compose.ymlis properly configured -
Start the services:
docker-compose up -d- Check service logs:
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f backend
docker-compose logs -f mysql- Stop the services:
docker-compose downThe docker-compose.yml includes:
- MySQL Service: Runs MySQL 8.0 with auto-initialization via
schema.sql - Backend Service: Node.js Express application
- Network: Custom network for service communication
- Volumes: Persistent MySQL data storage
docker build -t blog-backend .docker run -p 5000:3000 \
-e DB_HOST=mysql_host \
-e DB_USER=root \
-e DB_PASSWORD=517672 \
-e DB_NAME=blog_platform \
blog-backendhttp://localhost:5000/api
POST /auth/register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"role":"admin"
}Response (201):
{
"message": "User registered successfully",
}POST /auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "password123"
}Response (200):
{
"message": "Login successful",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
}POST /blog
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "My First Blog",
"content": "This is my first blog post...",
"summary": "A brief summary of the blog"
}Response (201):
{
"message": "Blog created successfully",
"blogId": 1
}GET /blogResponse (200):
{
"message": "Blogs retrieved successfully",
"blogs": [
{
"id": 1,
"title": "My First Blog",
"content": "This is my first blog post...",
"summary": "A brief summary of the blog",
"user_id": 1,
"created_at": "2026-02-07T10:30:00.000Z"
}
]
}GET /blog/:idResponse (200):
{
"message": "Blog retrieved successfully",
"blog": {
"id": 1,
"title": "My First Blog",
"content": "This is my first blog post...",
"summary": "A brief summary of the blog",
"user_id": 1,
"created_at": "2026-02-07T10:30:00.000Z"
}
}PUT /blog/:id
Authorization: Bearer {token}
Content-Type: application/json
{
"title": "Updated Title",
"content": "Updated content...",
"summary": "Updated summary"
}Response (200):
{
"message": "Blog updated successfully"
}DELETE /blog/:id
Authorization: Bearer {token}Response (200):
{
"message": "Blog deleted successfully"
}GET /user
Authorization: Bearer {token}Response (200):
{
"message": "Users retrieved successfully",
"users": [
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"created_at": "2026-02-07T10:30:00.000Z"
}
]
}GET /user/:id
Authorization: Bearer {token}Response (200):
{
"message": "User retrieved successfully",
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"created_at": "2026-02-07T10:30:00.000Z"
}
}All endpoints may return error responses:
{
"message": "Error message describing what went wrong"
}Common HTTP Status Codes:
200: Success201: Created400: Bad Request401: Unauthorized403: Forbidden404: Not Found500: Internal Server Error
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
password VARCHAR(255),
role ENUM('admin','user') DEFAULT 'user',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Description:
id: Unique identifier for each user (Auto-incremented)name: User's full name (max 100 characters)email: User's email address (unique, max 100 characters)password: Hashed password using bcryptjsrole: User role - either 'admin' or 'user' (default: 'user')created_at: Timestamp of user creation (auto-set to current time)
Indexes:
- Primary Key on
id - Unique constraint on
email
CREATE TABLE blogs (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
summary TEXT,
user_id INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);Description:
id: Unique identifier for each blog (Auto-incremented)title: Blog post title (max 255 characters)content: Full blog post content (unlimited text)summary: Brief summary of the blog (unlimited text)user_id: Foreign key referencing the user who wrote the blogcreated_at: Timestamp of blog creation (auto-set to current time)
Relationships:
- Foreign Key
user_idreferencesusers(id) ON DELETE CASCADE: When a user is deleted, all their blogs are deleted automatically
Indexes:
- Primary Key on
id - Foreign Key on
user_id
users (1) ---> (many) blogs
One user can have multiple blogs, but each blog belongs to only one user.
blog-backend/
├── src/
│ ├── app.js # Express app initialization
│ ├── config/
│ │ └── db.js # Database connection pool
│ ├── controllers/
│ │ ├── auth.controller.js # Auth endpoints logic
│ │ ├── blog.controller.js # Blog endpoints logic
│ │ └── user.controller.js # User endpoints logic
│ ├── middlewares/
│ │ ├── auth.middleware.js # JWT verification middleware
│ │ └── role.middleware.js # Role-based access control
│ ├── routes/
│ │ ├── auth.routes.js # Auth routes
│ │ ├── blog.routes.js # Blog routes
│ │ ├── user.routes.js # User routes
│ │ └── common.routes.js # Main API router
│ ├── services/
│ │ ├── auth.service.js # Auth business logic
│ │ └── blog.service.js # Blog business logic
│ └── utils/
│ ├── initializeDb.js # Database initialization
│ └── summary.js # Utility functions
├── schema.sql # Database initialization script
├── docker-compose.yml # Docker Compose configuration
├── Dockerfile # Docker image configuration
├── package.json # Project dependencies
└── README.md # This file
- Create a controller in
src/controllers/ - Add business logic to
src/services/if needed - Create routes in
src/routes/ - Update
src/routes/common.routes.jsto include new routes - Add middleware if authentication or role checks are needed
- User registers with email and password
- Password is hashed with bcryptjs
- User can login with email and password
- On successful login, a JWT token is returned
- Include token in
Authorization: Bearer {token}header for protected routes - Token is verified using
auth.middleware.js
admin: Can perform all actions including deleting blogsuser: Can read blogs, create/update own blogs, but cannot delete