Skip to content

ceckles/express-movies

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

23 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Backend Express API

A RESTful API built with Express.js, Prisma ORM, and PostgreSQL for managing movies and user watchlists. Features JWT authentication and Zod validation for request validation.

πŸ› οΈ Tech Stack

Node.js Express PostgreSQL Prisma JWT Zod Doppler JavaScript

  • Runtime: Node.js
  • Framework: Express.js 5.2.1
  • Database: PostgreSQL (via Neon)
  • ORM: Prisma 6.19.0
  • Authentication: JWT (jsonwebtoken)
  • Validation: Zod
  • Password Hashing: bcryptjs
  • Environment Variables: dotenv / Doppler
  • Secrets Management: Doppler
  • Package Manager: pnpm

πŸ“‹ Prerequisites

  • Node.js (v18 or higher)
  • pnpm (or npm/yarn)
  • PostgreSQL database (Neon, local, or cloud)
  • Git
  • Doppler CLI (optional, for secrets management)

πŸš€ Installation

  1. Clone the repository

    git clone <repository-url>
    cd backend-express
  2. Install dependencies

    pnpm install
  3. Set up environment variables

    Option A: Using Doppler (Recommended)

    Install Doppler CLI:

    # Linux/macOS
    curl -L --tlsv1.2 --proto "=https" -sSf https://cli.doppler.com/install.sh | sh
    
    # Or using Homebrew (macOS)
    brew install doppler
    
    # Or using npm/pnpm
    pnpm add -g doppler-cli

    Authenticate with Doppler:

    doppler login

    Link your project to a Doppler config:

    doppler setup

    This will prompt you to select:

    • Your Doppler project
    • The config (e.g., dev, staging, prod)

    Option B: Using .env file (Local Development)

    Create a .env file in the root directory:

    DATABASE_URL="postgresql://user:password@host:port/database"
    JWT_SECRET="your-secret-key-here"
    JWT_EXPIRES_IN="7d"
    PORT=5001
    NODE_ENV="development"
  4. Generate Prisma Client

    npx prisma generate
  5. Run database migrations

    npx prisma migrate dev
  6. Seed the database (optional)

    pnpm run seed:movies

βš™οΈ Configuration

Environment Variables

Variable Description Required Default
DATABASE_URL PostgreSQL connection string Yes -
JWT_SECRET Secret key for JWT tokens Yes -
JWT_EXPIRES_IN JWT token expiration time No 7d
PORT Server port No 5001 (dev) / 3000 (production)
NODE_ENV Environment mode No development/production

Secrets Management with Doppler

This project supports Doppler for secure secrets management. Doppler allows you to:

  • Store secrets securely in the cloud
  • Manage different configs (dev, staging, prod) per environment
  • Sync secrets across team members
  • Rotate secrets without code changes
  • Audit secret access

Setting up Doppler:

  1. Create a Doppler account at doppler.com

  2. Create a project in the Doppler dashboard

  3. Add your secrets to Doppler:

    • Go to your project β†’ Config (e.g., dev)
    • Add all required environment variables:
      • DATABASE_URL
      • JWT_SECRET
      • JWT_EXPIRES_IN
      • PORT
      • NODE_ENV
  4. Authenticate with Doppler:

    doppler login
  5. Verify secrets are loaded:

    doppler secrets -p backend-express -c dev

Using Doppler in different environments:

The project is configured to use the backend-express Doppler project. The scripts automatically use the correct config:

# Development (uses dev config)
pnpm run dev
# Equivalent to: doppler run -p backend-express -c dev -- nodemon src/server.js

# Production (uses prod config)
pnpm run start
# Equivalent to: doppler run -p backend-express -c prod -- node src/server.js

# For other configs, run directly:
doppler run -p backend-express -c staging -- node src/server.js

Note: The default scripts (pnpm run dev, pnpm run start) use Doppler with the backend-express project. Use dev:local or start:local scripts if you prefer using .env files.

Database Setup

  1. Create a PostgreSQL database (or use Neon)
  2. Add DATABASE_URL to your Doppler config or .env file
  3. Run migrations: npx prisma migrate dev

πŸƒ Running the Project

Development Mode

With Doppler (Recommended):

pnpm run dev

This uses Doppler to inject environment variables and starts the server with nodemon for auto-reloading.

With .env file (Local):

pnpm run dev:local

Production Mode

With Doppler:

pnpm run start

With .env file:

pnpm run start:local

The server will start on http://localhost:5001 (or your configured PORT).

Note: Make sure you have either:

  • Doppler configured (doppler setup) and authenticated (doppler login), OR
  • A .env file in the root directory with all required variables

πŸš€ Deployment

The application can be deployed to any platform that supports Node.js applications (e.g., Heroku, Railway, Render, AWS, DigitalOcean, etc.).

Deployment with Doppler

Doppler provides seamless integration with most deployment platforms:

  1. Install Doppler CLI in your deployment environment

  2. Authenticate using a service token:

    doppler configure set token <service-token>
  3. Update your start command to use Doppler with the project and config:

    doppler run -p backend-express -c prod -- node src/server.js

    Or use the npm script:

    pnpm run start

Platform-specific guides:

Deployment with Environment Variables

Note: Make sure to set all required environment variables when deploying. The app listens on 0.0.0.0 in production to allow external connections.

For platforms that don't support Doppler, set environment variables directly in your platform's dashboard or configuration.

πŸ“‘ API Endpoints

Authentication (/auth)

Method Endpoint Description Auth Required
POST /auth/register Register a new user No
POST /auth/login Login user No
POST /auth/logout Logout user No

Register Request Body:

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "password123"
}

Login Request Body:

{
  "email": "john@example.com",
  "password": "password123"
}

Movies (/movies)

Method Endpoint Description Auth Required
GET /movies Get all movies No
GET /movies/:id Get movie by ID No
POST /movies Create a new movie Yes
PUT /movies/:id Update a movie (creator only) Yes
DELETE /movies/:id Delete a movie (creator only) Yes

Create Movie Request Body:

{
  "title": "The Matrix",
  "overview": "A computer hacker learns about the true nature of reality",
  "releaseYear": 1999,
  "genres": ["Action", "Sci-Fi"],
  "runtime": 136,
  "posterUrl": "https://example.com/poster.jpg"
}

Update Movie Request Body:

{
  "title": "The Matrix Reloaded",
  "overview": "Neo continues his journey",
  "releaseYear": 2003,
  "genres": ["Action", "Sci-Fi"],
  "runtime": 138,
  "posterUrl": "https://example.com/poster2.jpg"
}

Delete Movie Response:

{
  "status": "success",
  "message": "Movie deleted successfully"
}

Note: All fields in the update request are optional. Only the creator of a movie can update or delete it.

Watchlist (/watchlist)

Method Endpoint Description Auth Required
POST /watchlist Add movie to watchlist Yes
PUT /watchlist/:id Update watchlist item Yes
DELETE /watchlist/:id Remove movie from watchlist Yes

Add to Watchlist Request Body:

{
  "movieId": "uuid",
  "status": "PLANNED",
  "rating": 5,
  "notes": "Looking forward to watching this"
}

Update Watchlist Request Body:

{
  "status": "COMPLETED",
  "rating": 8,
  "notes": "Great movie!"
}

Watchlist Status Values:

  • PLANNED
  • WATCHING
  • COMPLETED
  • DROPPED

Health Check

Method Endpoint Description
GET /health Server health check

πŸ“ Project Structure

backend-express/
β”œβ”€β”€ prisma/
β”‚   β”œβ”€β”€ schema.prisma      # Database schema
β”‚   β”œβ”€β”€ migrations/        # Database migrations
β”‚   └── seed.js           # Database seed file
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   └── db.js         # Database connection
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   └── watchlistController.js
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ authMiddleware.js
β”‚   β”‚   └── validateRequestMiddleware.js
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ authRoutes.js
β”‚   β”‚   β”œβ”€β”€ movieRoutes.js
β”‚   β”‚   └── watchlistRoutes.js
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   └── generateToken.js
β”‚   β”œβ”€β”€ validators/
β”‚   β”‚   β”œβ”€β”€ authValidator.js
β”‚   β”‚   └── watchlistValidator.js
β”‚   └── server.js         # Application entry point
β”œβ”€β”€ .env                  # Environment variables (not in git)
β”œβ”€β”€ .gitignore
β”œβ”€β”€ package.json
└── README.md

πŸ“œ Available Scripts

Script Description
pnpm run dev Start development server with nodemon (uses Doppler)
pnpm run dev:local Start development server with nodemon (uses .env file)
pnpm run start Start production server (uses Doppler)
pnpm run start:local Start production server (uses .env file)
pnpm run seed:movies Seed database with movie data (uses Doppler)
pnpm run seed:movies:local Seed database with movie data (uses .env file)
npx prisma generate Generate Prisma Client
npx prisma migrate dev Run database migrations
npx prisma studio Open Prisma Studio (database GUI)

πŸ” Authentication

The API uses JWT (JSON Web Tokens) for authentication.

  1. Register/Login to get a token
  2. Include the token in the Authorization header:
    Authorization: Bearer <your-jwt-token>
    
  3. Protected routes require valid authentication

βœ… Request Validation

The API uses Zod for request validation. All incoming request bodies are validated against predefined schemas before processing.

Validation Middleware

The validateRequestMiddleware validates request bodies using Zod schemas:

router.post('/', authMiddleware, validateRequestMiddleware(schema), controller);

Available Validators

  • authValidator.js - Validates registration and login requests
  • watchlistValidator.js - Validates watchlist operations
    • addToWatchlistSchema - Validates adding movies to watchlist
    • updateWatchlistItemSchema - Validates updating watchlist items

Validation Features

  • Type Safety - Ensures correct data types (UUID, string, number, enum)
  • Custom Error Messages - Provides clear validation error messages
  • Automatic Coercion - Converts compatible types (e.g., string to number)
  • Field Constraints - Enforces min/max values, string lengths, and enum values

Invalid requests return a 400 Bad Request with detailed error messages.

πŸ—„οΈ Database Schema

Models

  • User - User accounts with authentication

    • id (UUID)
    • name (String)
    • email (String, unique)
    • password (String, hashed)
    • createdAt (DateTime)
  • Movie - Movie information

    • id (UUID)
    • title (String)
    • overview (String, optional)
    • releaseYear (Int)
    • genres (String array)
    • runtime (Int, optional)
    • posterUrl (String, optional)
    • createdBy (String, foreign key to User)
    • createdAt (DateTime)
  • WatchlistItem - User's watchlist entries

    • id (UUID)
    • userId (String, foreign key to User)
    • movieId (String, foreign key to Movie)
    • status (WatchlistStatus enum)
    • rating (Int, optional)
    • notes (String, optional)
    • createdAt (DateTime)
    • updatedAt (DateTime)

See prisma/schema.prisma for full schema details.

πŸ› οΈ Development

Prisma Commands

# Generate Prisma Client
npx prisma generate

# Create a new migration
npx prisma migrate dev --name migration_name

# Reset database (WARNING: deletes all data)
npx prisma migrate reset

# View database in browser
npx prisma studio

Error Handling

The API uses try/catch blocks for error handling and returns appropriate HTTP status codes:

  • 200 - Success
  • 201 - Created
  • 400 - Bad Request (validation errors, invalid input, missing required fields)
  • 401 - Unauthorized (invalid or missing authentication)
  • 403 - Forbidden (insufficient permissions, e.g., not the creator)
  • 404 - Not Found (resource doesn't exist)
  • 409 - Conflict (resource cannot be deleted due to foreign key constraints)
  • 500 - Internal Server Error (server/database errors)

Validation Errors: When request validation fails (Zod), the API returns a 400 Bad Request with a message containing all validation errors.

🀝 Contributing

Contributions, issues, and feature requests are welcome!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors