Skip to content

Backend API

Lavesh Paryani edited this page Sep 26, 2026 · 1 revision

Backend API

backend/ is an Express 4 API (ES modules) backed by MySQL. It is complete enough to serve events, reviews and enquiries, but it is not deployed and the live frontend does not call it. Everything here applies when you run it locally or deploy it yourself.

Endpoints

Base URL: http://localhost:5000/api by default.

Method Path Validation / limits Behaviour
GET /health - { status: "OK" }
GET /reviews - All reviews, newest first. Cached for 1 hour when Redis is enabled
POST /reviews name, message, rating (1 to 5); 5 requests per 15 minutes per IP Inserts a review and clears the cached list
GET /events - Events dated today or later. Cached for 30 minutes when Redis is enabled
GET /events/:id - One event
POST /events title, date, location, optional description Creates an event
PUT /events/:id same as POST Updates an event
DELETE /events/:id - Deletes an event
POST /enquiry name, email, optional phone, message; 10 requests per 15 minutes per IP Trims and length-limits the fields, stores the enquiry, then emails a notification if SMTP is configured

Validation rules live in src/utils/validation.js (express-validator). Text fields are trimmed, length-checked and HTML-escaped, and emails are normalised. Failed validation returns 400 { error: "Validation failed", details: [...] }. Unknown routes return 404 { error: "Route not found" }, and other errors go through src/middleware/errorHandler.js.

The event write routes have no authentication. Add an auth layer (or remove the routes) before exposing the API publicly.

Database

src/config/database.js creates a mysql2/promise pool (10 connections, SSL when DB_SSL=true). src/models/initDatabase.js runs on every start and creates the tables if they do not exist:

Table Columns
reviews id, name, message, rating (1 to 5), created_at
events id, title, date, location, image, description, created_at, updated_at
enquiries id, name, phone, email, message, created_at

All queries use prepared statements (pool.execute with ? placeholders). There are no migrations beyond CREATE TABLE IF NOT EXISTS, so column changes must be applied by hand.

Email

src/controllers/enquiryController.js builds a Nodemailer SMTP transport from EMAIL_HOST, EMAIL_PORT (default 587), EMAIL_USER and EMAIL_PASS. When EMAIL_USER and EMAIL_PASS are set, each enquiry is emailed to the client's address. A failed email is logged and does not fail the request.

Caching

src/utils/cache.js connects to Redis only when REDIS_ENABLED=true and REDIS_URL is set. If Redis is missing or the connection fails, every cache call returns null or false and the API works without caching.

Security middleware

  • helmet with a Content Security Policy (default-src 'self', images from self, data: and https:), cross-origin resource policy set to cross-origin
  • cors allowing only FRONTEND_URL (any origin when NODE_ENV=development), with credentials
  • JSON and URL-encoded bodies limited to 10 MB
  • Graceful shutdown on SIGTERM / SIGINT closes Redis and the MySQL pool

Clone this wiki locally