Skip to content

25punam/Movie-API

Repository files navigation

🎬 Movie API

image image

🎬 Movie Search API β€” Scalable Data Engine

A high-performance movie discovery platform built with Django REST Framework, capable of searching and filtering 300,000+ records in real time. Features background data ingestion via Celery + Redis, a containerized Docker setup, and a responsive React.js frontend.


✨ Features

  • πŸ” Smart Search API β€” Multi-parameter filtering by title, language, genre, rating, and release year
  • ⚑ High Performance β€” DB indexed fields + optimized QuerySets on 300,000+ records
  • πŸ”„ Background Tasks β€” Celery workers fetch TMDB data without blocking the API
  • ⏰ Scheduled Jobs β€” Celery Beat auto-updates movie data on a schedule
  • πŸ“„ Pagination β€” Offset-based pagination for safe browsing of large datasets
  • πŸ–Ό Smart UI β€” Auto-hides movie cards when poster images are missing
  • 🐳 Fully Dockerized β€” One command starts the entire 6-service stack
  • πŸ“± Responsive Grid β€” 4-column movie layout built in React.js

πŸ›  Tech Stack

Layer Technology
Backend Django, Django REST Framework
Frontend React.js
Database PostgreSQL 15
Cache / Broker Redis
Task Queue Celery (Worker + Beat)
DevOps Docker, Docker Compose

πŸ— Architecture Overview

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  React.js   β”‚  ← Frontend (localhost:3000)
                    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                           β”‚ HTTP
                    β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
                    β”‚  Django API β”‚  ← DRF (localhost:8000)
                    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚              β”‚              β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ PostgreSQL  β”‚ β”‚   Redis   β”‚ β”‚  Celery Worker         β”‚
     β”‚  (Movies DB)β”‚ β”‚  (Broker) β”‚ β”‚  + Beat (Scheduler)    β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🐳 Docker Setup (Recommended)

All 6 services β€” Django, PostgreSQL, Redis, Celery Worker, Celery Beat, Redis Commander β€” start with a single command.

Services Started by Docker Compose

Service Description Port
web Django REST API 8000
db PostgreSQL 15 database 5432
redis Message broker for Celery 6379
celery_worker Processes background TMDB fetch tasks β€”
celery_beat Schedules periodic data sync tasks β€”
redis-commander Redis GUI for monitoring queues 8081

1️⃣ Clone the Repository

git clone https://github.com/25punam/movie-api.git
cd movie-api

2️⃣ Create Environment File

cp .env.example .env
# Open .env and fill in your credentials

.env should contain:

SECRET_KEY=your-django-secret-key
DEBUG=True

POSTGRES_DB=Movies
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-strong-password
DB_HOST=db
DB_PORT=5432

TMDB_API_KEY=your-tmdb-api-key

⚠️ Never commit your .env file to GitHub. Make sure it is listed in .gitignore.

3️⃣ Build and Start All Services

docker compose up --build

4️⃣ Run Migrations

docker compose exec web python manage.py migrate

5️⃣ Access the Services

Service URL
Django API http://localhost:8000
Redis Commander (GUI) http://localhost:8081

πŸ’» React Frontend Setup

The frontend runs separately from the Docker backend.

1️⃣ Navigate to Frontend Folder

cd frontend

2️⃣ Install Dependencies

npm install

3️⃣ Start Development Server

npm start

4️⃣ Access Frontend

http://localhost:3000

⚠️ Make sure the Docker backend is running before starting the frontend.


πŸ”Ž API Reference

Search Movies

GET /api/search/

Query Parameters

Parameter Type Description Example
q string Search by title or overview Inception
language string Filter by original language code en, hi, fr
genre string Filter by genre name or ID (comma-separated) Action or 28,12
min_rating float Minimum vote average (0–10) 7.5
release_year integer Filter by release year 2023
page integer Page number (default: 1) 2
limit integer Results per page (max: 100) 12

Example Requests

GET /api/search/?language=en&page=1&limit=12
GET /api/search/?q=inception&release_year=2010
GET /api/search/?genre=Action&min_rating=7.5&page=1
GET /api/search/?language=hi&genre=28,12&limit=20

Example Response

{
  "movies": [
    {
      "id": 27205,
      "title": "Inception",
      "original_language": "en",
      "release_date": "2010-07-16",
      "vote_average": 8.4,
      "popularity": 98.5,
      "poster_path": "https://image.tmdb.org/t/p/w500/..."
    }
  ],
  "total_count": 312000,
  "returned_count": 12,
  "page": 1,
  "page_size": 12,
  "limit": 12
}

βš™οΈ Celery β€” Background Tasks

Celery handles all TMDB data fetching in the background so the API stays fast and responsive at all times.

How It Works

User hits API  β†’  Django responds instantly (no waiting)

Meanwhile in background:
  Celery Beat (scheduler)
        ↓
  Triggers fetch task on schedule
        ↓
  Celery Worker fetches pages from TMDB API
        ↓
  Saves / updates 300,000+ records in PostgreSQL

Trigger a Fetch Task Manually

docker compose exec web python manage.py shell
from movies.tasks import fetch_movies
fetch_movies.delay()

Monitor Workers in Real Time

# Watch Celery worker logs
docker compose logs celery_worker -f

# Watch Celery Beat scheduler logs
docker compose logs celery_beat -f

πŸ“‚ Project Structure

movie-api/
β”‚
β”œβ”€β”€ movie_api/              # Django project config
β”‚   β”œβ”€β”€ settings.py
β”‚   β”œβ”€β”€ celery.py           # Celery app configuration
β”‚   └── urls.py
β”‚
β”œβ”€β”€ movies/                 # Core Django app
β”‚   β”œβ”€β”€ models.py           # Movie & Genre models with DB indexes
β”‚   β”œβ”€β”€ views.py            # MovieSearchAPIView (DRF APIView)
β”‚   β”œβ”€β”€ serializers.py      # DRF serializers
β”‚   β”œβ”€β”€ tasks.py            # Celery tasks β€” TMDB data fetch
β”‚   └── urls.py
β”‚
β”œβ”€β”€ frontend/               # React.js frontend
β”‚   β”œβ”€β”€ src/
β”‚   └── package.json
β”‚
β”œβ”€β”€ docker-compose.yml      # Orchestrates all 6 services
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .env.example            # Environment variable template
└── README.md

⚑ Performance Optimizations

  • Database Indexing β€” db_index=True applied on movie_id, title, original_language, popularity, vote_average, and release_date fields, enabling fast filtering and sorting across 300,000+ records without full table scans.

  • Paginated Responses β€” Offset-based pagination ensures only one page slice hits the DB at a time (queryset[offset : offset + page_size]), so 300,000+ records are never loaded into memory at once. Response size is capped at 100 items per request.

  • N+1 Query Prevention β€” Used prefetch_related("genres") to fetch all genre data in a single DB query instead of one query per movie row.

  • Django Q Objects β€” Multi-field search runs across title and overview in a single optimized OR query, with .distinct() preventing duplicate rows caused by ManyToMany genre joins.

  • Smart Default Limits β€” No-filter requests default to 100 results; filtered requests allow up to 500 β€” balancing performance with usability and preventing accidental rendering of 44,000+ records on a single filter.

  • Popularity + Rating Ordering β€” Results sorted by -popularity, -vote_average so the most relevant movies always appear first without any client-side sorting overhead.

  • Celery Async Tasks β€” TMDB API data ingestion runs entirely in background Celery workers, keeping the Django API fast during large data updates. Celery Beat automates scheduled syncs.

  • PostgreSQL over SQLite β€” Production-grade database handles concurrent API requests and 300,000+ records reliably, with full support for indexing and complex multi-parameter queries.

  • Docker Volumes β€” PostgreSQL data persists in a named Docker volume (postgres_db), so all 300,000+ records survive container restarts and full rebuilds safely.


πŸ›‘ Stopping the Project

# Stop all running containers
docker compose down

# Stop containers and delete all data volumes (resets the database)
docker compose down -v

🌟 Future Improvements

  • Redis caching for frequent search queries
  • Elasticsearch integration for full-text search
  • Movie recommendation system
  • JWT Authentication for user accounts
  • CI/CD pipeline with GitHub Actions
  • AWS ECS production deployment

πŸ“„ License

MIT License β€” feel free to use and modify.

About

A REST API for managing movie data using Django and Django REST Framework.

Resources

Stars

Watchers

Forks

Contributors