A Node.js/Express backend application for managing movies and user watchlists. Built with PostgreSQL, Prisma ORM, JWT authentication, and comprehensive validation.
This backend API provides a complete authentication and movie management system with user watchlist functionality. Users can register, log in, manage movie collections, and maintain personal watchlists with status tracking.
- Runtime: Node.js with ES Modules
- Framework: Express.js 5.x
- Database: PostgreSQL with Prisma ORM
- Authentication: JWT (JSON Web Tokens) with bcryptjs password hashing
- Validation: Zod for request validation
- Development: Nodemon for hot reloading
- Additional: Cookie Parser for secure session handling
- Node.js (v18+)
- PostgreSQL database
- Environment variables configured
-
Clone/Navigate to the project
git clone https://github.com/ESE-MONDAY/backend.git cd backend -
Install dependencies
npm install
-
Configure environment variables Create a
.envfile in the root directory with:DATABASE_URL=postgresql://user:password@localhost:5432/database_name JWT_SECRET=your_secret_key PORT=5001 -
Set up the database
npx prisma migrate dev
-
Seed initial data (optional)
npm run seedmovies
-
Start the server
npm run dev # Development with hot reload npm start # Production mode
If you prefer to run the app in Docker, use one of these options.
docker build -t movie-watchlist-backend .
docker run -p 5001:5001 --env-file .env movie-watchlist-backenddocker-compose up --build -dThe app will be exposed at
http://localhost:5001inside the container.
If you use Docker with a local .env file, Docker Compose will load environment variables from .env automatically.
The server will run on http://localhost:5001
All routes are prefixed with /api/v1
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/register |
Register a new user | ✗ |
POST |
/login |
Authenticate user and receive JWT tokens | ✗ |
POST |
/refresh-token |
Refresh access token using refresh token | ✓ |
POST |
/logout |
Logout user (invalidate session) | ✓ |
Register/Login Request Body:
{
"email": "user@example.com",
"password": "securePassword123"
}All movie endpoints require authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Get all movies with pagination |
GET |
/:id |
Get a specific movie by ID |
POST |
/ |
Add a new movie (admin/creator only) |
DELETE |
/:id |
Delete a movie |
Add Movie Request Body:
{
"title": "Movie Title",
"overview": "Movie description",
"releaseYear": 2024,
"genres": ["Drama", "Thriller"],
"runtime": 120,
"posterUrl": "https://image.url/poster.jpg"
}All watchlist endpoints require authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Get user's watchlist |
POST |
/ |
Add movie to watchlist |
PUT |
/:id |
Update watchlist item status |
DELETE |
/:id |
Remove movie from watchlist |
Add to Watchlist Request Body:
{
"movieId": "movie-uuid",
"status": "watching" // Options: "watching", "completed", "dropped"
}Update Watchlist Item Request Body:
{
"status": "completed",
"rating": 8.5
}id(UUID) - Primary keyname- User's full nameemail(Unique) - User's email addresspassword- Hashed passwordcreatedAt- Account creation timestamp
id(UUID) - Primary keytitle(Unique) - Movie titleoverview- Plot summaryreleaseYear- Release yeargenres- Array of genre tagsruntime- Duration in minutesposterUrl- Movie poster image URLcreatedBy- Creator user ID (FK)createdAt- Creation timestamp
id(UUID) - Primary keyuserId- User ID (FK)movieId- Movie ID (FK)status- Watching/Completed/Droppedrating- User's ratingaddedAt- Date added to watchlist
id(UUID) - Primary keyuserId- User ID (FK)refreshToken- JWT refresh tokenexpiresAt- Token expiration timestamp
This project includes interactive API documentation using Swagger UI. After starting the server, you can access the documentation at:
URL via Nginx: http://localhost:8080/api/docs
Direct app URL: http://localhost:5001/api/docs
- Interactive API explorer
- Try out endpoints directly in the browser
- Detailed request/response schemas
- Authentication support with JWT tokens
- Real-time API specifications
- Start the development server:
npm run dev - Open your browser and navigate to:
http://localhost:8080/api/docs - You'll see all available endpoints organized by tags (Authentication, Movies, Watchlist)
- Click on any endpoint to see details and try it out
- For protected endpoints, click "Authorize" and paste your JWT token
When adding new endpoints, include JSDoc comments with Swagger annotations:
/**
* @swagger
* /api/v1/example:
* get:
* summary: Brief description
* tags:
* - Category
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success response
*/npm run dev # Start development server with nodemon
npm start # Start production server
npm run seedmovies # Seed database with movie data
npm test # Run tests (not configured yet)src/
├── server.js # Express app setup and entry point
├── config/
│ └── db.js # Database connection logic
├── controller/
│ ├── authController.js # Authentication handlers
│ ├── movieController.js # Movie management handlers
│ └── watchlistController.js # Watchlist handlers
├── middleware/
│ ├── auth-middleware.js # JWT verification middleware
│ └── validateRequest.js # Request validation middleware
├── routes/
│ ├── authRoutes.js # Auth endpoint definitions
│ ├── movieRoutes.js # Movie endpoint definitions
│ ├── watchlistRoutes.js # Watchlist endpoint definitions
│ └── v1/
│ └── index.js # API v1 router aggregator
├── utils/
│ └── generateToken.js # JWT token generation
└── validators/
├── movieValidator.js # Movie request schemas (Zod)
└── watchlistValidator.js # Watchlist request schemas (Zod)
prisma/
├── schema.prisma # Database schema definition
├── seed.js # Database seed script
└── migrations/ # Migration history
✅ User Authentication with JWT tokens
✅ Secure password hashing with bcryptjs
✅ Movie database management
✅ Personal watchlist with status tracking
✅ Request validation with Zod
✅ PostgreSQL with Prisma ORM
✅ Graceful server shutdown handling
✅ Cookie-based session management
✅ Error handling and validation middleware
- User registers with email and password
- Password is hashed and stored in database
- User logs in with credentials
- Server returns
accessToken(short-lived) andrefreshToken(long-lived) - Access token used in Authorization header:
Bearer <accessToken> - When access token expires, use refresh token to obtain new one
- Tokens are validated via
authMiddlewareon protected routes
The API returns standard HTTP status codes:
200- Success201- Created400- Bad Request (validation error)401- Unauthorized (missing/invalid token)403- Forbidden (insufficient permissions)404- Not Found500- Server Error
- API is versioned at
/api/v1/ - All protected routes use JWT bearer tokens
- Watchlist items track user preferences and ratings
- Movie titles are unique in the system
- User emails are unique identifiers
Author: Ese Monday
License: ISC