A robust backend API for a Medium-like blogging platform built with Node.js, Express, Prisma, and PostgreSQL.
-
π Authentication & Authorization
- JWT-based authentication with refresh tokens
- Role-based access control (Admin, Author, Reader)
- Email verification and password reset
-
π Content Management
- CRUD operations for articles, comments, and tags
- Draft and published article states
- Article likes and reading time calculation
-
π Advanced Search System
- Global search across articles, users, and tags
- Advanced filtering and sorting options
- Search suggestions and autocomplete
- Trending search terms
- Search history for authenticated users
- Full-text search capabilities
-
π₯ User Management
- User profiles with bio and avatar
- Follow/unfollow system
- User activity tracking
-
π‘οΈ Security Features
- API rate limiting
- Input validation and sanitization
- CORS protection
- Helmet for security headers
-
π€ File Upload
- Profile image upload
- Article cover image upload
- File type and size validation
-
π§ Email System
- Account verification emails
- Password reset emails
- Background job processing
-
π API Features
- RESTful API design
- Comprehensive error handling
- Pagination support
- API documentation with Swagger
- Runtime: Node.js
- Framework: Express.js
- Database: PostgreSQL
- ORM: Prisma
- Authentication: JWT
- Validation: Zod
- File Upload: Multer
- Email: Nodemailer
- Testing: Jest + Supertest
- Documentation: Swagger/OpenAPI
- Node.js (v16 or higher)
- PostgreSQL
- Redis (for background jobs)
-
Clone the repository
git clone <repository-url> cd medium-clone-backend
-
Install dependencies
npm install
-
Environment Setup
# Copy the environment template cp environment-variables.example .envIMPORTANT: Fill in ALL required environment variables in
.envbefore starting the application. SECURITY: Never use default passwords. Generate strong, unique passwords for each service. -
Database Setup
# Generate Prisma client npm run prisma:generate # Run database migrations npm run prisma:migrate # (Optional) Seed the database npm run prisma:seed
-
Start the server
# Development npm run dev # Production npm start
# Application Settings
NODE_ENV=development
PORT=3000
# Database Configuration (PostgreSQL) - ALL REQUIRED
POSTGRES_DB=medium_clone_db
POSTGRES_USER=medium_user
POSTGRES_PASSWORD=your_secure_database_password_here
DATABASE_URL="postgresql://username:password@localhost:5432/medium_clone_db"
# Redis Configuration - REQUIRED
REDIS_PASSWORD=your_secure_redis_password_here
REDIS_URL=redis://:your_secure_redis_password_here@localhost:6379
# JWT Configuration - REQUIRED
JWT_SECRET=your_super_secure_jwt_secret_minimum_32_characters
JWT_REFRESH_SECRET=your_super_secure_refresh_secret_minimum_32_characters
JWT_EXPIRES_IN=1d
JWT_REFRESH_EXPIRES_IN=7d
# Email Configuration (SMTP)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=[email protected]
SMTP_PASS=your_app_password_here
FROM_EMAIL=[email protected]
FROM_NAME=Medium Clone
# Frontend Configuration
FRONTEND_URL=http://localhost:3001# File Upload Settings
MAX_FILE_SIZE=5242880
# Rate Limiting
RATE_LIMIT_MAX_REQUESTS=100
RATE_LIMIT_WINDOW_MS=900000
# Security Settings
SECURITY_WEBHOOK_URL=
SECURITY_ALERT_EMAIL=
# Postman API Integration
POSTMAN_API_KEY=
POSTMAN_COLLECTION_ID=
POSTMAN_ENVIRONMENT_ID=- Use strong, unique passwords for all services
- JWT secrets must be at least 32 characters long
- Never commit the .env file to version control
- Use different credentials for dev/staging/production environments
- Regularly rotate passwords and secrets
POST /api/auth/register- Register new userPOST /api/auth/login- User loginPOST /api/auth/refresh- Refresh access tokenPOST /api/auth/verify-email- Verify email addressPOST /api/auth/forgot-password- Request password resetPOST /api/auth/reset-password- Reset password
GET /api/users/profile- Get current user profilePUT /api/users/profile- Update user profilePOST /api/users/avatar- Upload avatarGET /api/users/:id- Get user by IDPOST /api/users/:id/follow- Follow userDELETE /api/users/:id/follow- Unfollow user
GET /api/articles- Get all articlesPOST /api/articles- Create new articleGET /api/articles/:id- Get article by IDPUT /api/articles/:id- Update articleDELETE /api/articles/:id- Delete articlePOST /api/articles/:id/like- Like articleDELETE /api/articles/:id/like- Unlike article
GET /api/articles/:id/comments- Get article commentsPOST /api/articles/:id/comments- Create commentPUT /api/comments/:id- Update commentDELETE /api/comments/:id- Delete comment
GET /api/tags- Get all tagsPOST /api/tags- Create new tagGET /api/tags/:slug- Get tag by slug
GET /api/search/global- Global search across articles, users, and tagsGET /api/search/articles- Advanced article search with filtersGET /api/search/users- Search usersGET /api/search/tags- Search tagsGET /api/search/suggestions- Get search suggestions (autocomplete)GET /api/search/trending- Get trending search termsGET /api/search/history- Get user's search historyDELETE /api/search/history- Clear user's search historyGET /api/search/fulltext- Full-text search using PostgreSQL
npm start # Start production server
npm run dev # Start development server with nodemon
npm test # Run tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage report
npm run prisma:generate # Generate Prisma client
npm run prisma:migrate # Run database migrations
npm run prisma:studio # Open Prisma Studio
npm run prisma:seed # Seed database with sample data
# Postman Collection Management
npm run postman:test-connection # Test Postman API connection
npm run postman:push # Push both collection and environment to Postman
npm run postman:pull # Pull both collection and environment from Postman
npm run postman:sync # Sync files bidirectionally
npm run postman:push-collection # Push only collection to Postman
npm run postman:pull-collection # Pull only collection from Postman
npm run postman:push-environment # Push only environment to Postman
npm run postman:pull-environment # Pull only environment from PostmanThis project includes automated Postman collection management. The collection includes all API endpoints with proper authentication and test scripts.
-
Get your Postman API Key
- Go to Postman Settings
- Generate a new API key
-
Get Collection and Environment IDs
- Collection ID: Found in collection settings or URL
- Environment ID: Found in environment settings
-
Add to your .env file
POSTMAN_API_KEY=PMAK-your-api-key-here POSTMAN_COLLECTION_ID=your-collection-id POSTMAN_ENVIRONMENT_ID=your-environment-id
# Test connection
npm run postman:test-connection
# Push local changes to Postman
npm run postman:push
# Pull latest from Postman
npm run postman:pull
# Sync both ways (compares timestamps)
npm run postman:syncYou can also use the script directly with command line arguments:
node scripts/update-postman.js test-connection --api-key YOUR_KEY --collection-id YOUR_COLLECTION_ID --environment-id YOUR_ENV_IDsrc/
βββ config/ # Configuration files
βββ controllers/ # Route controllers
βββ middleware/ # Custom middleware
βββ routes/ # API routes
βββ services/ # Business logic
βββ utils/ # Utility functions
βββ validations/ # Zod validation schemas
βββ app.js # Express app setup
prisma/
βββ schema.prisma # Database schema
βββ migrations/ # Database migrations
βββ seed.js # Database seeder
tests/ # Test files
uploads/ # File uploads (created at runtime)
The API uses consistent error response format:
{
"success": false,
"error": "ERROR_TYPE",
"message": "Human readable error message",
"errors": [] // Optional validation errors
}Common HTTP status codes:
200- Success201- Created400- Bad Request401- Unauthorized403- Forbidden404- Not Found409- Conflict429- Too Many Requests500- Internal Server Error
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverage- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see the LICENSE file for details.