Skip to Content
URL Shortener - Project Specification

Source: Jolli-sample-repos/url-shortener  Last Updated: 4/8/2026


URL Shortener - Project Specification

Project Overview

Domain: Utilities / URL Management Language: TypeScript Complexity: Simple (5-10 files) Type: RESTful API with OpenAPI/Swagger documentation

A URL shortening service that creates short, memorable links for long URLs, tracks click analytics, and provides redirect functionality.


Feature Requirements

1. URL Shortening

  • Create short URLs from long URLs
  • Generate random short codes (6-8 characters)
  • Optional custom short codes (if available)
  • Validate URL format before creating
  • Prevent duplicate long URLs (return existing short code)

2. URL Redirection

  • Redirect short URLs to original long URLs
  • Return 404 for non-existent short codes
  • Track redirect count on each access

3. URL Management

  • Retrieve URL details by short code
  • List all URLs (paginated)
  • Delete URLs by short code
  • Update long URL for existing short code

4. Analytics

  • Track total clicks per short URL
  • Track last accessed timestamp
  • Get top URLs by click count
  • Global statistics (total URLs, total clicks)

5. Validation & Expiry

  • URL format validation
  • Optional expiration date for short URLs
  • Return 410 Gone for expired URLs

API Endpoints Specification

Base URL: /api/v1

MethodEndpointDescriptionRequest BodyResponse
POST/urlsCreate a short URL{ longUrl, customCode?, expiresAt? }201: ShortUrl, 400: Invalid URL/Code Taken
GET/urls/:shortCodeGet URL detailsNone200: ShortUrl, 404: Not Found
GET/urlsList all URLsQuery: page, limit200: { urls: ShortUrl[], total, page, limit }
PUT/urls/:shortCodeUpdate long URL{ longUrl }200: ShortUrl, 404: Not Found
DELETE/urls/:shortCodeDelete short URLNone204: No Content, 404: Not Found
GET/r/:shortCodeRedirect to long URLNone302: Redirect, 404: Not Found, 410: Expired
GET/statsGet global statisticsNone200: GlobalStats
GET/stats/topGet top URLs by clicksQuery: limit (default: 10)200: ShortUrl[]

Data Models

interface ShortUrl { shortCode: string; longUrl: string; createdAt: string; expiresAt?: string; clicks: number; lastAccessedAt?: string; } interface CreateUrlRequest { longUrl: string; customCode?: string; // 4-20 alphanumeric characters expiresAt?: string; // ISO 8601 format } interface UpdateUrlRequest { longUrl: string; } interface GlobalStats { totalUrls: number; totalClicks: number; activeUrls: number; expiredUrls: number; } interface PaginatedResponse { urls: ShortUrl[]; total: number; page: number; limit: number; hasMore: boolean; }

Folder Structure

url-shortener/ ├── src/ │ ├── index.ts # Entry point & Express setup │ ├── routes.ts # All route definitions │ ├── models.ts # TypeScript interfaces & types │ ├── storage.ts # In-memory data storage │ ├── validator.ts # URL and code validation │ ├── generator.ts # Short code generation logic │ └── swagger.ts # OpenAPI/Swagger configuration ├── package.json ├── tsconfig.json ├── .gitignore ├── README.md └── PROJECT_SPEC.md

Tech Stack

Core Dependencies

  • Runtime: Node.js 18+
  • Framework: Express.js 4.x
  • Language: TypeScript 5.x
  • Validation: zod or joi
  • Documentation: swagger-ui-express, swagger-jsdoc
  • Utilities: nanoid (for short code generation)

Dev Dependencies

  • ts-node
  • @types/node
  • @types/express
  • nodemon

Database Schema

Note: This simple version uses in-memory storage (Map). No actual database required.

// In-memory storage structure const urls: Map<string, ShortUrl> = new Map(); const longUrlIndex: Map<string, string> = new Map(); // longUrl -> shortCode

Short Code Generation Logic

  • Use nanoid or custom base62 encoding
  • Default length: 6-8 characters
  • Character set: [a-zA-Z0-9]
  • Collision detection: regenerate if code exists
  • Custom codes: validate format and availability

Setup Instructions Template

Prerequisites

  • Node.js 18 or higher
  • npm or yarn

Installation

npm install

Development

npm run dev

Build

npm run build

Run Production

npm start

Configuration

Environment variables:

PORT=3000 BASE_URL=http://localhost:3000 SHORT_CODE_LENGTH=6

API Documentation

Access Swagger UI at: http://localhost:3000/api-docs


OpenAPI Documentation Requirements

  • All endpoints must be documented with OpenAPI 3.0 specification
  • Include request/response schemas
  • Include example requests and responses
  • Document query parameters for pagination
  • Include error response schemas (400, 404, 410, 500)
  • Document redirect behavior for /r/:shortCode endpoint

Success Criteria

  1. All 8 endpoints are functional and return correct responses
  2. Short code generation works without collisions
  3. Custom short codes can be created if available
  4. Redirects work correctly and increment click count
  5. Expired URLs return 410 status
  6. Analytics accurately track clicks and timestamps
  7. Pagination works correctly for URL listing
  8. OpenAPI/Swagger documentation is complete and accessible
  9. Code is well-structured and follows TypeScript best practices
  10. README includes clear setup and usage instructions