A robust and scalable RESTful API for managing tours, built with modern Node.js technologies and best practices. This project demonstrates advanced Express.js features, MongoDB integration, comprehensive error handling, and professional API design patterns.
- Complete CRUD Operations for tour management
- Advanced Filtering & Querying with custom APIFeatures class
- Pagination & Sorting for optimized data retrieval
- Field Selection to minimize data transfer
- Comprehensive Error Handling with custom error classes
- Data Validation using Mongoose schemas
- Aggregation Pipeline for statistical analysis
- ES6+ Modules with modern JavaScript syntax
- Async/Await error handling with custom catchAsync wrapper
- MongoDB Integration with Mongoose ODM
- Environment Configuration with dotenv
- Development Logging with Morgan middleware
- Static File Serving for images and assets
- Professional Error Responses for development and production
- Runtime: Node.js
- Framework: Express.js 5.1.0
- Database: MongoDB with Mongoose 8.16.3
- Environment Management: dotenv 17.2.0
- Logging: Morgan 1.10.0
- Development: Nodemon 3.1.10
- Query Parsing: qs 6.14.0
natours/
βββ controllers/ # Route handlers and business logic
β βββ errorController.js # Global error handling
β βββ tourController.js # Tour-related operations
β βββ userController.js # User-related operations
βββ Models/ # Database models and schemas
β βββ tourModel.js # Tour data model
βββ routes/ # API route definitions
β βββ tourRoutes.js # Tour endpoints
β βββ userRoutes.js # User endpoints
βββ utils/ # Utility functions and classes
β βββ apifeatures.js # Query enhancement utilities
β βββ appError.js # Custom error class
β βββ catchAsync.js # Async error wrapper
β βββ jsonUtils.js # JSON manipulation utilities
βββ dev-data/ # Sample data and import scripts
βββ public/ # Static assets (CSS, images, HTML)
βββ app.js # Express application configuration
βββ server.js # Server startup and database connection
βββ .env # Environment variables
- Node.js (v14 or higher)
- MongoDB Atlas account or local MongoDB installation
- Git
-
Clone the repository
git clone https://github.com/AhmedEsam2002/natours.git cd natours -
Install dependencies
npm install
-
Environment Configuration Create a
.envfile in the root directory:PORT=5000 MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/natours?retryWrites=true&w=majority NODE_ENV=development
-
Start the application
# Development mode with auto-restart npm run dev # Production mode npm start
-
Access the API
- Base URL:
http://localhost:5000 - API Base:
http://localhost:5000/api/v1
- Base URL:
| Method | Endpoint | Description | Parameters |
|---|---|---|---|
| GET | /api/v1/tours |
Get all tours | Query parameters for filtering |
| POST | /api/v1/tours |
Create new tour | Request body with tour data |
| GET | /api/v1/tours/:id |
Get tour by ID | Tour ID in URL |
| PUT | /api/v1/tours/:id |
Update tour | Tour ID + request body |
| DELETE | /api/v1/tours/:id |
Delete tour | Tour ID in URL |
| GET | /api/v1/tours/stats |
Get tour statistics | None |
| GET | /api/v1/tours/monthly-plan/:year |
Get monthly plan | Year in URL |
- Filtering:
?difficulty=easy&price[lt]=500 - Sorting:
?sort=price,-ratingsAverage - Field Selection:
?fields=name,duration,price - Pagination:
?page=2&limit=10
{
name: String (required),
duration: Number (required),
maxGroupSize: Number (required),
difficulty: String (enum: ['easy', 'medium', 'difficult']),
ratingsAverage: Number (1-5, default: 4.5),
ratingsQuantity: Number (default: 0),
price: Number (required),
summary: String (required),
description: String,
imageCover: String (required),
images: [String],
startDates: [String],
createdAt: Date (default: Date.now)
}The APIFeatures class provides:
- Advanced Filtering: Support for MongoDB operators (gte, gt, lte, lt)
- Flexible Sorting: Multiple field sorting with direction control
- Field Limitation: Select specific fields to reduce bandwidth
- Pagination: Efficient data chunking with skip/limit
- Development Mode: Detailed error information with stack traces
- Production Mode: User-friendly error messages
- Custom Error Types: CastError, ValidationError, and Duplicate Key handling
- Operational vs Programming Errors: Distinction for better debugging
const catchAsync = (fn) => {
return (req, res, next) => {
fn(req, res, next).catch((err) => next(err));
};
};- Group tours by difficulty level
- Calculate average ratings and prices
- Count tours and ratings per difficulty
- Tours scheduled by month for a given year
- Count of tours per month
- List of tour names for each month
- Input Validation: Mongoose schema validation
- Error Sanitization: Different error responses for dev/prod
- Environment Variables: Sensitive data protection
- Modular Architecture: Separation of concerns
- RESTful Design: Standard HTTP methods and status codes
- Database Indexing: Optimized queries with proper indexing
- Pagination: Prevent large data transfers
- Field Selection: Reduce bandwidth usage
- Virtual Properties: Computed fields without database storage
- Query Optimization: Efficient MongoDB operations
GET http://localhost:5000/api/v1/toursGET http://localhost:5000/api/v1/tours?difficulty=easy&price[lt]=500GET http://localhost:5000/api/v1/tours?sort=-price&page=1&limit=5POST http://localhost:5000/api/v1/tours
Content-Type: application/json
{
"name": "Amazing Adventure Tour",
"duration": 10,
"maxGroupSize": 12,
"difficulty": "medium",
"price": 699,
"summary": "An incredible adventure through beautiful landscapes",
"imageCover": "tour-cover.jpg"
}All API responses follow a consistent format:
{
"status": "success" | "fail" | "error",
"results": number, // For collections
"data": {
"tours": [...] | object // Response data
}
}npm run dev: Start development server with auto-reloadnpm start: Start production server
- nodemon: Auto-restart server on file changes
- ndb: Advanced Node.js debugging
- morgan: HTTP request logging
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the ISC License.
Ahmed Esam
- GitHub: @AhmedEsam2002
- Built as part of Jonas Schmedtmann's Node.js course
- MongoDB Atlas for database hosting
- Express.js community for excellent documentation
Note: This project is for educational purposes and demonstrates modern Node.js development practices including error handling, database integration, and RESTful API design.