docs
Architecture
How the URL Shortener is structured — modules, data flow, and design decisions.
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 alphabetAliasPolicy— validates custom aliases (3–32 chars,[A-Za-z0-9_-])UrlValidator— rejects malformed or unsafe URLsRedirectEvent,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 |
Data Flow: Creating a Short Link
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 |