Skip to content

samayine/tourguide-api

Repository files navigation

TourGuide API

A production-ready API for tour management. Built for performance, security, and developer experience.

Node.js Express MongoDB Docker License


Architecture

TourGuide/
├── src/
│   ├── config/            # Env validation & typed config export
│   ├── controllers/       # Route handlers (auth, tours, users, health)
│   ├── logging/           # Winston structured logger
│   ├── middlewares/       # Custom middleware (request logger)
│   ├── models/            # Mongoose schemas with indexes & middleware
│   ├── routes/            # Express router definitions
│   ├── utils/             # Reusable helpers (APIFeatures, AppError, etc.)
│   └── app.js             # Express app factory
├── logs/                  # Auto-generated rotating log files
├── Dockerfile             # Multi-stage production image
├── docker-compose.yml     # Orchestrates app + MongoDB
└── server.js              # Entry point (DB connect + graceful shutdown)

Features

Security

Feature Implementation
Security Headers helmet — sets 15+ protective HTTP headers
Rate Limiting express-rate-limit — 100 req/hr per IP on all /api routes
NoSQL Injection express-mongo-sanitize — strips $ and . from query inputs
XSS Protection xss-clean — sanitizes HTML from request body/query/params
Parameter Pollution hpp — prevents duplicate query params with a whitelist
CORS cors — configurable cross-origin resource sharing
JWT Auth jsonwebtoken — stateless Bearer token authentication
Password Hashing bcryptjs — with configurable salt rounds
Body Limit express.json({ limit: '10kb' }) — prevents oversized payloads

Database Performance

Feature Implementation
Compound Index { price: 1, ratingsAverage: -1 } — optimises most common filter/sort
Slug Index { slug: 1 } — fast lookup by URL-friendly slug
Lean Queries .lean() on getAllTours + getTour — returns plain JS objects, ~5× faster
Slow Query Log Post-find middleware warns if query exceeds 100ms
Rating Setter ratingsAverage rounds to 1 decimal in the DB layer

Observability

Feature Implementation
Structured Logging Winston JSON logs with service + environment context
HTTP Access Logs Morgan piped into Winston's http level
Log Rotation winston-daily-rotate-file — 14-day combined, 30-day error
Error Visibility All 4xx/5xx errors logged with URL, method, IP
Health Endpoint GET /api/v1/health — DB state + uptime (used by Docker HEALTHCHECK)

DevOps / Docker

Feature Implementation
Multi-stage Build deps stage + production stage — minimal final image
Non-root User adduser appuser — containers never run as root
Docker HEALTHCHECK Polls /api/v1/health every 30s
Dev Hot-reload docker-compose.override.yml mounts src/ and runs nodemon
Named Volumes MongoDB data persists across container restarts
Graceful Shutdown SIGTERM/SIGINT → drain connections → close DB → exit 0

API Endpoints

Tours

Method Endpoint Auth Description
GET /api/v1/tours 🔒 Get all tours (filterable, sortable, paginated)
GET /api/v1/tours/:id Public Get single tour
POST /api/v1/tours 🔒 admin/lead-guide Create a tour
PATCH /api/v1/tours/:id 🔒 admin/lead-guide Update a tour
DELETE /api/v1/tours/:id 🔒 admin Delete a tour
GET /api/v1/tours/top-5-cheap Public Alias — top 5 cheapest tours
GET /api/v1/tours/tour-stats Public Aggregated stats by difficulty
GET /api/v1/tours/monthly-plan/:year 🔒 Monthly tour schedule

Users & Auth

Method Endpoint Auth Description
POST /api/v1/users/signup Public Register a new user
POST /api/v1/users/login Public Login and receive JWT
POST /api/v1/users/forgotPassword Public Request password reset email
GET /api/v1/users 🔒 Get all users

System

Method Endpoint Auth Description
GET /api/v1/health Public DB + uptime health check

Query String Features

All list endpoints support:

  • Filtering: ?price[lte]=1000&difficulty=easy
  • Sorting: ?sort=-ratingsAverage,price
  • Field Selection: ?fields=name,price,duration
  • Pagination: ?page=2&limit=10

Quick Start

Option 1 — Docker (Recommended)

# Copy example env file and fill in your values
cp config.env.example config.env

# Start app + MongoDB with one command
npm run docker:up

# App will be available at → http://localhost:8000
# Health check                → http://localhost:8000/api/v1/health

Option 2 — Local Development

# Prerequisites: Node.js 22+, MongoDB running locally

npm install
# Edit config.env with your local MongoDB URI
npm run dev

Tech Stack

  • Runtime: Node.js 22 (LTS)
  • Framework: Express 4.x
  • Database: MongoDB 7 via Mongoose 5 ODM
  • Auth: JSON Web Tokens (JWT)
  • Logging: Winston + winston-daily-rotate-file
  • Security: Helmet, express-rate-limit, express-mongo-sanitize, xss-clean, hpp, cors
  • Containerisation: Docker, Docker Compose
  • Dev tooling: Nodemon, ESLint (Airbnb), Prettier

Environment Variables

Variable Required Description
NODE_ENV development or production
PORT Server port (default: 8000)
DATABASE MongoDB connection URI
JWT_SECRET HS256 signing secret (min 32 chars)
JWT_EXPIRES_IN Token lifespan e.g. 90d
EMAIL_HOST SMTP host (Mailtrap for dev)
EMAIL_PORT SMTP port
EMAIL_USERNAME SMTP username
EMAIL_PASSWORD SMTP password

Built by Sam Ayine · GitHub

About

RESTful API for tour booking system built with Node.js, Express, and MongoDB. Features JWT authentication, role-based access control, and advanced querying capabilities.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors