Skip to content

Bharat1Rajput/Url-Shortner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

URL Shortener Service (Go, Gin, GORM, Redis, Postgres)

This project is a production-style URL shortener service written in Go. It demonstrates layered architecture, dependency injection, Redis caching, Redis-based rate limiting, and PostgreSQL persistence using GORM.

Architecture Overview

  • Handler layer (internal/handler): Gin HTTP handlers, request/response mapping and validation.
  • Service layer (internal/service): Business logic, short code generation, caching, rate limiting, analytics.
  • Repository layer (internal/repository): GORM-based data access for the urls table.
  • Cache layer (internal/cache): Redis-backed cache for short_code -> original_url.
  • Rate limiter (internal/ratelimiter): Redis-backed fixed-window rate limiter.
  • Models (internal/models): GORM models for persistence.
  • Utilities (pkg/base62): Base62 encoder for generating short codes from numeric IDs.

Request flow:

Client → Gin Handler → Service → Redis cache lookup → DB fallback → Response

Data Model

Table: urls

  • id (uint64, primary key, auto-increment)
  • short_code (unique index)
  • original_url
  • click_count
  • created_at
  • expires_at
  • last_accessed

cmd/server/main.go performs GORM AutoMigrate on startup to create/update the table.

API Endpoints

  • POST /shorten

    Request body:

    {
      "url": "https://example.com/very-long-url",
      "custom_alias": "optional",
      "expires_in": "optional duration, e.g. \"24h\""
    }

    Response:

    {
      "short_code": "abc123",
      "short_url": "http://localhost:8080/abc123",
      "expires_at": "2026-03-07T12:00:00Z"
    }
  • GET /:short_code

    Redirects (302) to the original URL. Uses Redis cache first, then DB. Updates click_count and last_accessed.

  • GET /stats/:short_code

    Returns analytics:

    {
      "short_code": "abc123",
      "original_url": "https://example.com/very-long-url",
      "click_count": 42,
      "created_at": "2026-03-07T11:00:00Z",
      "last_accessed": "2026-03-07T11:59:00Z",
      "expires_at": "2026-03-08T11:00:00Z"
    }

Rate Limiting

  • Implemented in internal/ratelimiter using Redis fixed windows.
  • Rule: max 10 URL creations per minute per client IP.
  • If exceeded, POST /shorten returns 429 Too Many Requests.

Redis Caching

  • Implemented in internal/cache.
  • Caches short_code -> original_url.
  • Redirect handler checks Redis first, then falls back to DB and refreshes cache.
  • Cache TTL defaults to 24h but is capped by the URL's expiration time when set.

Running with Docker Compose

Prerequisites: Docker and Docker Compose.

docker compose up --build

Services:

  • postgres – PostgreSQL 16
  • redis – Redis 7
  • app – Go service on port 8080

The app container is configured via environment variables (see docker-compose.yml and configs/config.example.env).

Local Development (without Docker)

  1. Start PostgreSQL and Redis locally.
  2. Export environment variables (example in configs/config.example.env).
  3. Run the server:
go run ./cmd/server

Notes on Design

  • Dependency injection: All core components (URLRepository, URLCache, RateLimiter, URLService) are constructed and wired in cmd/server/main.go.
  • Context usage: Every repository, cache, and rate limiter method accepts a context.Context derived from the HTTP request.
  • Error handling: The service layer exposes domain errors, which handlers translate into HTTP status codes.
  • Short code generation: Uses Base62 encoding of the database ID when no custom alias is provided; custom aliases are supported and validated for uniqueness.

About

URL shortener service in Go with Redis caching and PostgreSQL for fast redirects, custom aliases, and analytics tracking.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors