Overview

The URL Shortener is a 4-module Maven reactor built on plain Java 26 with zero external framework dependencies. Each module has a single, well-defined responsibility.

graph TB
    Browser["🌐 Browser / Client"]
    UI["urlshortener-ui\nVaadin Flow WAR\n:8080"]
    Server["urlshortener-server\nREST Admin API\n:9090"]
    Redirect["Redirect Server\n:8081"]
    Core["urlshortener-core\nDomain Model"]
    Client["urlshortener-client\nJava HTTP Client"]
    Store["Storage Layer\nIn-Memory / EclipseStore"]

    Browser -->|"Short link GET /{code}"| Redirect
    Browser -->|"Manage links"| UI
    UI -->|"HTTP REST"| Client
    Client -->|"HTTP/JSON"| Server
    Server --> Core
    Server --> Store
    Redirect --> Store

Modules

urlshortener-core

The shared domain model. Has no dependencies on the other modules.

  • ShortUrlMapping — the central entity (shortCode, originalUrl, active, expiresAt)
  • Base62Encoder — generates short codes from a 62-character alphabet
  • AliasPolicy — validates custom aliases (3–32 chars, [A-Za-z0-9_-])
  • UrlValidator — rejects malformed or unsafe URLs
  • RedirectEvent, HourlyAggregate, DailyAggregate — statistics models

urlshortener-server

The runtime process. Starts two com.sun.net.httpserver.HttpServer instances.

Instance Port Handler
Admin API 9090 AdminApiHandler — full CRUD + import/export
Redirect 8081 RedirectHandler — resolves short codes, records events

Storage is injected via interface:

UrlMappingStore  ──→  InMemoryUrlMappingStore
                  └─→  EclipseStoreUrlMappingStore

urlshortener-client

A pure-Java HTTP client for the Admin API. Used by the UI and useful for scripting or CI pipelines.

Key classes: URLShortenerClient, StatisticsClient, AdminClient, ColumnVisibilityClient

urlshortener-ui

A Vaadin Flow 25 web application packaged as a WAR for Jetty 12.

Views:

View Path Description
CreateView /create Form to create/edit short links
OverviewView /overview Grid with all mappings, filters, pagination
StatisticsView /statistics Hourly/daily charts
StatisticsDetailView /statistics/{code} Per-link deep dive
AboutView /about Project info

sequenceDiagram
    actor User
    participant UI as Vaadin UI
    participant Client as URLShortenerClient
    participant Server as Admin API :9090
    participant Core as Core (AliasPolicy)
    participant Store as Storage

    User->>UI: Fill form, click "Shorten"
    UI->>Client: createShortUrl(originalUrl, alias)
    Client->>Server: POST /api/shorten (JSON)
    Server->>Core: validate alias + URL
    Core-->>Server: OK / ValidationError
    Server->>Store: save(ShortUrlMapping)
    Store-->>Server: stored
    Server-->>Client: 201 Created + ShortUrlMapping
    Client-->>UI: ShortUrlMapping
    UI-->>User: Display short link

Data Flow: Redirect

sequenceDiagram
    actor Visitor
    participant Redirect as Redirect Server :8081
    participant Store as Storage
    participant Stats as StatisticsStore

    Visitor->>Redirect: GET /oss-project
    Redirect->>Store: lookup("oss-project")
    Store-->>Redirect: ShortUrlMapping
    Redirect->>Stats: record(RedirectEvent)
    Redirect-->>Visitor: 302 → originalUrl

Storage Architecture

flowchart TB
    UrlMappingStore["UrlMappingStore
interface
save(mapping)
findByCode(code)
findAll()
delete(code)"] StatisticsStore["StatisticsStore
interface
record(event)
getHourly(code)
getDaily(code)"] InMemoryStore["InMemoryUrlMappingStore
ConcurrentHashMap data"] EclipseStore["EclipseStoreUrlMappingStore
EmbeddedStorageManager manager
DataRoot root
"] StatisticsImpl["StatisticsStore implementation
redirect events and aggregates"] UrlMappingStore -. implemented by .-> InMemoryStore UrlMappingStore -. implemented by .-> EclipseStore StatisticsStore -. implemented by .-> StatisticsImpl InMemoryStore -->|"development mode"| Runtime["Server runtime"] EclipseStore -->|"persistent mode"| Runtime StatisticsImpl --> Runtime

Design Decisions

Decision Choice Reason
HTTP server JDK HttpServer Zero dependencies, educational clarity
Serialization Jackson 3 Industry standard, lightweight
Persistence EclipseStore Pure-Java, no SQL schema migration
UI Vaadin Flow 25 Server-side Java, no manual JS
Build Maven multi-module Standard Java tooling
Short codes Base62 URL-safe, compact, well-understood