Skip to content

A URL shortener built with NestJS, Prisma, Redis, and Passport.js. Features OAuth login with Google/GitHub, Redis caching, session management, soft deletion, and Docker Compose setup. Built to learn, experiment, and push backend skills further.

License

Notifications You must be signed in to change notification settings

mohanad-80/short-url

Repository files navigation

Short URL Service

A full-stack-ready, production-grade URL shortener built with NestJS, Prisma, Passport.js, and Redis.
This project was created to learn, experiment, and try new technologies including:

  • Third-party authentication (OAuth) with Google and GitHub using Passport.js
  • Docker and Docker Compose for containerization and orchestration
  • Caching with Redis (via Docker Compose)
  • Advanced NestJS features: custom guards, decorators, DTO validation, Prisma exception handling, and more

Table of Contents


Features

  • Shorten URLs: Authenticated users can create, update, delete, and list their own short URLs.
  • Third-Party Authentication: Login with Google or GitHub using OAuth 2.0 (Passport.js).
  • Session Management: Secure sessions with express-session and Passport.
  • Caching: Redis-backed cache for fast URL lookups and reduced DB load.
  • Rate Limiting: Multiple throttling strategies using NestJS Throttler.
  • Validation: DTO validation with Joi and custom NestJS pipes.
  • Soft Delete: URLs are soft-deleted (marked with deletedAt), not removed from DB.
  • Statistics: Track and retrieve access counts for each short URL.
  • Prisma ORM: Type-safe DB access, migrations, and seeding.
  • Error Handling: Custom Prisma exception filter for user-friendly errors.
  • Dockerized: Production-ready Dockerfile and Compose setup (app + Redis).
  • Environment Config: All secrets and configs via .env file.
  • Extensible: Modular NestJS codebase, ready for new features.

Architecture Overview

  • NestJS: Main backend framework (controllers, modules, DI, etc.)
  • Prisma: ORM for PostgreSQL (models: Users, ShortURLs)
  • Supabase: Hosting the PostgreSQL database
  • Passport.js: Handles OAuth with Google and GitHub
  • Redis: Used as a cache for short URL lookups
  • Docker Compose: Orchestrates the app and Redis containers

How It Works (Diagrams)

Architecture

system architecture

Shortening flow

url shortening flow sequence diagram

Auth flow

auth flow sequence diagram


Getting Started

Prerequisites

1. Clone the Repo

git clone https://github.com/your-username/short-url.git
cd short-url

2. Configure Environment

Copy .env.example to .env and fill in your secrets:

cp .env.example .env
# Edit .env with your DB, OAuth, and session secrets

3. Build server image with Docker

docker build --build-arg DATABASE_URL=db-url \
--build-arg DIRECT_URL=db-direct-url \
-t opt-nest-short-url .

4. Run with Docker Compose

docker compose up

4. (Optional) Local Development

Install dependencies and run in watch mode:

npm install
npm run start:dev

Environment Variables

See .env:

  • DATABASE_URL - PostgreSQL connection string
  • DIRECT_URL - Direct DB connection (for migrations)
  • GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET - Google OAuth
  • GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET - GitHub OAuth
  • SESSION_SECRET - Secret for session encryption
  • FRONTEND_URL - Allowed CORS origin and redirect target
  • REDIS_URL - Redis connection string (redis://redis_cache:6379 for Docker Compose)

API Endpoints

Auth

  • GET /auth/google/login - Start Google OAuth
  • GET /auth/google/redirect - Google OAuth callback
  • GET /auth/github/login - Start GitHub OAuth
  • GET /auth/github/redirect - GitHub OAuth callback
  • GET /auth/logout - Logout and destroy session
  • GET /auth/status - Get current user info (if authenticated)

Shorten

  • POST /shorten - Create a new short URL (body: { url: string })
  • GET /shorten/all - List all user's short URLs
  • GET /shorten/:short - Get info for a specific short URL
  • PUT /shorten/:short - Update a short URL
  • DELETE /shorten/:short - Soft-delete a short URL
  • GET /shorten/:short/stats - Get stats for a short URL

Redirect

  • GET /:short - Redirect to the original URL

Authentication Flow

  • Uses Passport.js with Google and GitHub strategies
  • On successful OAuth, user is created or updated in DB
  • Session is stored using express-session (cookie-based)
  • Custom session serializer for minimal session data
  • Logout endpoint destroys session and clears cookie

Caching & Redis

  • Uses @nestjs/cache-manager with @keyv/redis for Redis integration
  • Short URL lookups are cached for 1 hour
  • Cache is checked before DB on each redirect
  • Redis runs as a service in Docker Compose

Docker & Docker Compose

  • Dockerfile: Multi-stage build (builder + production)
  • compose.yml: Runs app and Redis, mounts Redis data volume
  • .dockerignore: Ignores node_modules, dist, .env, .git
  • Environment: All secrets/configs injected at runtime

Testing

  • Currently no tests are implemented.

Project Structure

src/
  app.controller.ts         # Handles redirects
  app.module.ts             # Root module
  app.service.ts            # Redirect logic, caching
  main.ts                   # App bootstrap, session, passport
  auth/                     # Auth module (OAuth, guards, session)
    auth.controller.ts
    auth.service.ts
    utils/
      google.guard.ts
      github.guard.ts
      authenticated.guard.ts
      session-serializer.ts
      user.decorator.ts
      google.strategy.ts
      github.strategy.ts
  shorten/                  # Shorten module (CRUD for short URLs)
    shorten.controller.ts
    shorten.service.ts
    dto/
  prisma/                   # Prisma service, exception filter
    prisma.service.ts
    prisma-client-exception/
  common/pipes/             # Joi validation pipe
  utils/                    # Nanoid generator
prisma/
  schema.prisma             # DB schema
  seed.ts                   # Seed script
Dockerfile
compose.yml
.env

Tech Stack

  • NestJS (TypeScript)
  • Prisma (ORM)
  • Supabase (PostgreSQL)
  • Passport.js (OAuth)
  • Redis (Cache)
  • Docker / Docker Compose
  • Joi (Validation)
  • Jest (Testing)

License

This project is licensed under the MIT License.

About

A URL shortener built with NestJS, Prisma, Redis, and Passport.js. Features OAuth login with Google/GitHub, Redis caching, session management, soft deletion, and Docker Compose setup. Built to learn, experiment, and push backend skills further.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published