A production-ready RESTful API built with Node.js, Express, and MySQL for managing a full-featured blogging platform, designed to be SEO-friendly and similar to Dev.to and Medium.com. The system enables users to register, create posts, comment, react, bookmark, and follow other users or publications. Admins and publication owners can efficiently manage roles, tags, and content approval workflows.
The API follows a modular, scalable architecture with robust authentication, authorization, validation, testing, and documentation, making it ideal for building high-performance, content-rich blogging platforms.
- JWT-based authentication and authorization
- Role-based access control (User, Editor, Owner, Admin)
- User management (profile, followers/following, notifications)
- Article and publication management (CRUD)
- Commenting system with nested routes
- Article reactions and views tracking
- Bookmarking system
- Tag management (Admin only)
- Publication membership and approval workflows
- Request validation using Zod
- Automated API testing with Jest and Supertest
- Runtime: Node.js
- Framework: Express.js
- Database: MySQL / MariaDB
- Authentication: JWT
- Validation: Zod
- Testing: Jest, Supertest
- Node.js v18 or higher
- MySQL or MariaDB v10 or higher
- npm (comes with Node.js)
git clone https://github.com/imranmalakzai/blog-api
cd blog-apinpm installfill the example .env.development.local file in the project root:
HOST_URI="localhost"
DB_password=""
DB_NAME="blog_api"
DB_USER="root"
CORS_ORIGIN="*"
PORT=5000
ACCESS_TOKEN="your_access_token"
ACCESS_TOKEN_EXPIRE='1h'
REFRESH_TOKEN="your_refresh_token"
REFRESH_TOKEN_EXPIRE='7d'
- Open your MySQL client (Workbench, phpMyAdmin, etc.)
- Locate the SQL schema file inside the
schemadirectory - Execute the SQL script to create tables
npm run startRun automated tests:
npm run test- Base URL:
http://localhost:5000/api
POST /api/auth/register— Register a new userPOST /api/auth/login— User loginPOST /api/auth/logout— Logout current userPOST /api/auth/refresh— Refresh access token
GET /api/users/me— Get current user profilePATCH /api/users/me— Update profilePATCH /api/users/me/avatar— Update profile avatarPATCH /api/users/me/password— Change passwordDELETE /api/users/me— Delete accountGET /api/users/me/followers— Get my followersGET /api/users/me/following— Get users I am following
GET /api/users/me/notifications— Get all notificationsGET /api/users/me/notifications/:notificationId/read— Read a notificationPOST /api/users/me/notifications/read-all— Mark all notifications as readDELETE /api/users/me/notifications/:notificationId— Delete a notification
GET /api/users— Get all usersGET /api/users/@:username— Get user by usernameGET /api/users/@:username/articles— Get articles by a userGET /api/users/@:username/followers— Get user followersGET /api/users/@:username/following— Get users the user followsPOST /api/users/@:username/follow— Follow a userDELETE /api/users/@:username/follow— Unfollow a userGET /api/users/@:username/articles/:articleSlug— Get a specific article by slug
PATCH /api/users/@:username/role— Change user roleGET /api/users/role?role=user|editor|admin— Get users by role
POST /api/articles— Create a new article (Auth required)GET /api/articles— Get all articlesGET /api/articles/:articleSlug— Get article by slugPATCH /api/articles/:articleSlug— Update an article (Auth required)DELETE /api/articles/:articleSlug— Delete an article (Auth required)
/api/articles/:articleSlug/comments— Article comments/api/articles/:articleSlug/reactions— Article reactions/api/articles/:articleSlug/views— Article views
POST /api/articles/:articleSlug/reactions— React to an article (Auth required)GET /api/articles/:articleSlug/reactions— Get all reactions for an article
GET /api/articles/:articleSlug/views— Get total views for an article
POST /api/bookmarks/articles/:articleSlug— Bookmark an articleGET /api/bookmarks/articles/:articleSlug— Get a bookmarked articleDELETE /api/bookmarks/articles/:articleSlug— Remove a bookmarked articleGET /api/bookmarks— Get all bookmarked articles
POST /api/articles/:articleSlug/comments— Create a commentGET /api/articles/:articleSlug/comments— Get all comments for an articleGET /api/articles/:articleSlug/comments/:commentId— Get a specific commentPATCH /api/articles/:articleSlug/comments/:commentId— Update a commentDELETE /api/articles/:articleSlug/comments/:commentId— Delete a comment
POST /api/publications— Create a new publication (Auth required)GET /api/publications— Get all publicationsGET /api/publications/:publicationSlug— Get a publication by slugPATCH /api/publications/:publicationSlug— Update a publication (Auth required)DELETE /api/publications/:publicationSlug— Delete a publication (Auth required)
/api/publications/:publicationSlug/articles— Publication articles/api/publications/:publicationSlug/members— Publication members
GET /api/publications/:publicationSlug/articles— Get all articles in a publicationGET /api/publications/:publicationSlug/articles/:articleSlug— Get a specific articlePOST /api/publications/:publicationSlug/articles— Create a new article (Owner, Editor, Writer; Auth required)PATCH /api/publications/:publicationSlug/articles/:articleSlug— Update article content (Owner, Editor, Writer; Auth required)DELETE /api/publications/:publicationSlug/articles/:articleSlug— Delete an article (Owner, Writer; Auth required)
GET /api/publications/:publicationSlug/review-articles— Get all articles under review (Owner, Editor)PATCH /api/publications/:publicationSlug/review-articles/:articleSlug/approve— Approve/Publish an article (Owner, Editor)PATCH /api/publications/:publicationSlug/review-articles/:articleSlug/reject— Reject an article (Owner, Editor, Writer)
/api/publications/:publicationSlug/articles/:articleSlug/comments— Article comments/api/publications/:publicationSlug/articles/:articleSlug/reactions— Article reactions/api/publications/:publicationSlug/articles/:articleSlug/views— Article views
POST /api/publications/:publicationSlug/follow— Follow a publication (Auth required)DELETE /api/publications/:publicationSlug/follow— Unfollow a publication (Auth required)GET /api/publications/:publicationSlug/followers— Get all followers of a publication (Auth required)GET /api/publications/:publicationSlug/members— Get all members of a publication (Auth required)DELETE /api/publications/:publicationSlug/members/:username— Remove a member (Owner only; Auth required)PATCH /api/publications/:publicationSlug/members/:username— Change a member's role (Owner only; Auth required)
POST /api/tags— Create a tag (Admin only)GET /api/tags— Get all tagsGET /api/tags/:slug— Get tag by slugPATCH /api/tags/:slug— Update a tagDELETE /api/tags/:slug— Delete a tag (Admin only)
GET /api/reactions— Get all reactionsGET /api/reactions/:reactionId— Get a reaction by IDPOST /api/reactions— Create a new reactionPOST /api/reactions/:reactionId— Update a reactionDELETE /api/reactions/:reactionId— Delete a reaction
This project is licensed under the MIT License. See the LICENSE file for more information.
