A robust, production-ready REST API for e-commerce platforms built with Node.js, Express, and PostgreSQL. This API provides comprehensive functionality for user management, product catalog operations, shopping cart workflows, order processing, and secure checkout transactions.
This API follows a modular architecture pattern with clear separation of concerns:
- Authentication Layer: JWT-based authentication with Passport.js and bcrypt password hashing
- Business Logic Layer: Organized route handlers for different domains (products, carts, orders, checkout)
- Data Access Layer: PostgreSQL with raw SQL queries for optimal performance
- API Documentation: Swagger/OpenAPI integration for interactive API documentation
- Session Management: Express-session for user state management
- Runtime: Node.js 18+
- Framework: Express.js 4.19+
- Database: PostgreSQL 13+
- Authentication: JWT + Passport.js + bcrypt
- Documentation: Swagger UI
- Session Management: express-session
- Development: PostCSS + Tailwind CSS (for static assets)
- Features
- Prerequisites
- Installation
- Configuration
- Usage
- API Endpoints
- Examples
- Project Structure
- Development
- Testing
- Deployment
- Troubleshooting
- Contributing
- License
- User registration with secure password hashing
- JWT-based authentication with access tokens
- Session management for persistent login state
- Secure logout functionality
- Full CRUD operations for product catalog
- Product search and filtering capabilities
- Stock management and inventory tracking
- Product metadata and descriptions
- Automatic cart creation for registered users
- Add, update, remove cart items
- Cart persistence across sessions
- Real-time cart total calculations
- Order placement and status tracking
- Order history for users
- Order item details and pricing
- Order status management
- Transactional checkout process
- Cart-to-order conversion
- Price validation and stock verification
- Atomic transaction handling
- Interactive Swagger UI at
/api-docs - OpenAPI 3.0 specification
- Request/response examples
- Authentication guides
Before running this application, ensure you have the following installed:
- Node.js: Version 18.0.0 or higher
- PostgreSQL: Version 13.0 or higher
- npm: Latest stable version (comes with Node.js)
- Git: For version control
- Operating System: Linux, macOS, or Windows
- Memory: Minimum 512MB RAM
- Storage: Minimum 1GB free space
- Network: Open ports for HTTP/HTTPS traffic
git clone <repository-url>
cd e-commerce-rest-apinpm installThis will install all required dependencies and generate the package-lock.json file.
-- Connect to PostgreSQL as superuser
CREATE DATABASE ecommerce;
CREATE USER ecommerce WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE ecommerce TO ecommerce;# Connect to your PostgreSQL instance and run:
psql -U ecommerce -d ecommerce -f db/init_db.sql# Copy the example environment file
cp .env.example .envEdit the .env file with your specific configuration:
# Server Configuration
PORT=3000
NODE_ENV=development
# Security
SESSION_SECRET=your-super-secret-session-key-change-this-in-production
ACCESS_TOKEN_SECRET=your-super-secret-access-token-key-change-this-in-production
# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_USER=ecommerce
DB_PASSWORD=your_secure_password
DB_NAME=ecommerce
DB_SSL=false# Development mode
npm start
# Or run directly with Node.js
node index.jsThe API server will start on http://localhost:3000
- Visit
http://localhost:3000/api-docsto access Swagger UI - The API documentation should load successfully
- All endpoints should be available for testing
| Variable | Description | Required | Default |
|---|---|---|---|
PORT |
Server port number | No | 3000 |
NODE_ENV |
Environment mode | No | development |
SESSION_SECRET |
Session encryption key | Yes | - |
ACCESS_TOKEN_SECRET |
JWT token secret | Yes | - |
DB_HOST |
PostgreSQL host | No | localhost |
DB_PORT |
PostgreSQL port | No | 5432 |
DB_USER |
Database username | Yes | - |
DB_PASSWORD |
Database password | Yes | - |
DB_NAME |
Database name | Yes | - |
DB_SSL |
Enable SSL for DB | No | false |
- Always change default secrets in production
- Use strong passwords for database credentials
- Enable SSL in production environments
- Rotate secrets regularly
- Use environment-specific configurations
Before accessing protected endpoints, users must authenticate and obtain a JWT token.
curl -X POST http://localhost:3000/register \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe",
"email": "[email protected]",
"password": "securepassword123"
}'curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{
"username": "johndoe",
"password": "securepassword123"
}'Use the returned JWT token in the Authorization header for subsequent requests:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:3000/protected-endpoint| Method | Endpoint | Description |
|---|---|---|
| POST | /register |
Register a new user |
| POST | /login |
User login |
| POST | /logout |
User logout |
| Method | Endpoint | Description |
|---|---|---|
| GET | /products |
Get all products |
| GET | /products/:id |
Get product by ID |
| POST | /products |
Create new product (Admin) |
| PUT | /products/:id |
Update product (Admin) |
| DELETE | /products/:id |
Delete product (Admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /cart |
Get user's cart |
| POST | /cart/items |
Add item to cart |
| PUT | /cart/items/:id |
Update cart item quantity |
| DELETE | /cart/items/:id |
Remove item from cart |
| DELETE | /cart |
Clear entire cart |
| Method | Endpoint | Description |
|---|---|---|
| GET | /orders |
Get user's orders |
| GET | /orders/:id |
Get order by ID |
| POST | /checkout |
Checkout cart (creates order) |
| Method | Endpoint | Description |
|---|---|---|
| POST | /checkout |
Process checkout and create order |
# Register user
curl -X POST http://localhost:3000/register \
-H "Content-Type: application/json" \
-d '{
"username": "customer1",
"email": "[email protected]",
"password": "mypassword123"
}'
# Login to get token
TOKEN=$(curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username": "customer1", "password": "mypassword123"}' \
| jq -r '.token')# Get all products
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/products# Add item to cart
curl -X POST http://localhost:3000/cart/items \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"product_id": 1, "quantity": 2}'
# View cart
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/cart# Process checkout
curl -X POST http://localhost:3000/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
# View orders
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/ordersconst axios = require('axios');
// Configure API client
const apiClient = axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json'
}
});
// Login function
async function login(username, password) {
try {
const response = await apiClient.post('/login', {
username,
password
});
return response.data.token;
} catch (error) {
console.error('Login failed:', error.response.data);
}
}
// Get products function
async function getProducts(token) {
try {
const response = await apiClient.get('/products', {
headers: {
Authorization: `Bearer ${token}`
}
});
return response.data;
} catch (error) {
console.error('Failed to fetch products:', error.response.data);
}
}
// Usage example
async function main() {
const token = await login('customer1', 'mypassword123');
const products = await getProducts(token);
console.log('Available products:', products);
}
main();e-commerce-rest-api/
βββ db/ # Database related files
β βββ init_db.sql # Database schema and initialization
βββ public/ # Static assets
β βββ index.html # Static HTML page
β βββ script.js # Frontend JavaScript
β βββ style.css # Stylesheet
βββ routes/ # API route handlers
β βββ auth.js # Authentication routes
β βββ products.js # Product management routes
β βββ cart.js # Shopping cart routes
β βββ orders.js # Order management routes
β βββ checkout.js # Checkout processing routes
βββ swagger/ # API documentation
β βββ swagger.json # OpenAPI specification
βββ .env.example # Environment variables template
βββ .gitignore # Git ignore patterns
βββ db.js # Database connection and queries
βββ index.js # Application entry point
βββ package.json # Project dependencies and scripts
βββ passport-config.js # Passport authentication configuration
βββ postcss.config.js # PostCSS configuration
βββ tailwind.config.js # Tailwind CSS configuration
βββ README.md # Project documentation
index.js: Main application file with Express setup, middleware configuration, and route mountingdb.js: Database connection pool and query helper functionspassport-config.js: Passport.js authentication strategy configurationroutes/: Modular route handlers organized by feature domainsdb/init_db.sql: Complete database schema with tables, indexes, and relationships
- Clone and install as described in Installation
- Set up your IDE with Node.js support
- Install PostgreSQL and create development database
- Configure environment variables for development
- Start development server:
npm start
The codebase follows a modular structure:
- Route handlers are organized by feature (products, cart, orders, etc.)
- Database queries are centralized in
db.js - Authentication logic is contained in
passport-config.js - Business logic is separated from HTTP concerns
- Create route handler in
routes/directory - Add database queries to
db.js - Update Swagger documentation
- Add tests for new endpoints
- Update this README with new features
# Syntax check
npm test
# Or run directly
node --check index.jsUse the Swagger UI at http://localhost:3000/api-docs to test endpoints interactively.
- User registration and login flow
- Product CRUD operations
- Cart management functionality
- Checkout process
- Order creation and retrieval
- Error handling for invalid requests
- Set
NODE_ENV=production - Use strong, unique secrets for
SESSION_SECRETandACCESS_TOKEN_SECRET - Enable
DB_SSL=truefor secure database connections - Configure production database credentials
- Set up reverse proxy (nginx recommended)
- Configure SSL/TLS certificates
- Set up monitoring and logging
- Configure firewall rules
# Production environment variables
PORT=3000
NODE_ENV=production
SESSION_SECRET=your-production-session-secret-here
ACCESS_TOKEN_SECRET=your-production-jwt-secret-here
DB_HOST=your-production-db-host
DB_PORT=5432
DB_USER=your-db-user
DB_PASSWORD=your-secure-db-password
DB_NAME=ecommerce_prod
DB_SSL=trueFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]Problem: ECONNREFUSED or connection timeout errors
Solutions:
- Verify PostgreSQL is running:
sudo systemctl status postgresql - Check database credentials in
.envfile - Ensure database exists and user has permissions
- Verify firewall settings allow connections
Problem: JWT token errors or login failures
Solutions:
- Check
ACCESS_TOKEN_SECRETin environment variables - Verify user credentials and password hashing
- Ensure JWT token is included in Authorization header
- Check token expiration settings
Problem: EADDRINUSE error on startup
Solutions:
- Change
PORTin.envfile - Kill process using the port:
lsof -ti:3000 | xargs kill - Check if another instance is running
Problem: Missing dependencies or import errors
Solutions:
- Run
npm installto install dependencies - Check Node.js version compatibility
- Verify all required packages are listed in
package.json - Clear npm cache:
npm cache clean --force
Enable debug logging by setting:
NODE_ENV=development
DEBUG=express:*- Check the API documentation at
/api-docs - Review application logs for error details
- Verify environment configuration
- Test database connectivity separately
We welcome contributions from the community! Here's how you can help:
- Fork the repository on GitHub
- Clone your fork locally
- Create a feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
npm install - Make your changes
- Test your changes thoroughly
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
feature/- New features or enhancementsbugfix/- Bug fixeshotfix/- Critical production fixesdocs/- Documentation updatesrefactor/- Code refactoring
<type>(<scope>): <description>
[optional body]
[optional footer]
Types: feat, fix, docs, style, refactor, test, chore
Example:
feat(auth): add OAuth2 authentication support
- Add OAuth2 provider configuration
- Update authentication middleware
- Add new login endpoints
Closes #123
- Use ES6+ features
- Follow async/await patterns for asynchronous code
- Use meaningful variable and function names
- Add JSDoc comments for complex functions
- Use parameterized queries to prevent SQL injection
- Follow consistent naming conventions
- Add proper indexing for performance
- Include error handling for database operations
- Follow RESTful conventions
- Use appropriate HTTP status codes
- Include proper error messages
- Validate input data
- Add tests for new features
- Ensure existing tests pass
- Test error conditions and edge cases
- Update API documentation for new endpoints
- Update README for new features
- Add inline code comments
- Update Swagger documentation
- Include usage examples
- Create a pull request with a clear title and description
- Reference any related issues
- Include screenshots for UI changes
- Wait for code review and feedback
- Address any requested changes
- Merge approved pull requests
- Be respectful and inclusive
- Use welcoming and inclusive language
- Be collaborative and open-minded
- Focus on what is best for the community
- Show empathy towards other community members
This project is licensed under the ISC License - see the LICENSE file for details.
Happy coding! π
For questions, issues, or contributions, please visit our GitHub repository.