# sujaydevx/url-shortner architecture

> Architecture diagram of the GitHub repository sujaydevx/url-shortner, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sujaydevx/url-shortner
- Repository: https://github.com/sujaydevx/url-shortner

## Overview

#### Purpose and Runtime
This is a Java/Gradle URL-shortening service, built as a Spring Boot application. It creates shortened URLs, resolves short codes into redirects, tracks URL usage, supports expiration, and exposes operational health/metrics. The process starts at `src/main/java/com/sujay/urlshortener/UrlShortenerApplication.java`; HTTP entry points are in `src/main/java/com/sujay/urlshortener/controller/UrlController.java` and `src/main/java/com/sujay/urlshortener/controller/HomeController.java`.

#### HTTP API and Boundary Layer
Controllers accept URL-shortening requests and redirect/statistics-facing traffic, using request/response DTOs to isolate the HTTP contract from domain persistence: `src/main/java/com/sujay/urlshortener/dto/request/ShortenUrlRequest.java`, `src/main/java/com/sujay/urlshortener/dto/response/ShortenUrlResponse.java`, and `src/main/java/com/sujay/urlshortener/dto/response/UrlStatsResponse.java`. Cross-origin behavior and API documentation configuration are centralized in `src/main/java/com/sujay/urlshortener/Config/CorsConfig.java` and `src/main/java/com/sujay/urlshortener/Config/OpenApiConfig.java`.

#### Core URL Lifecycle
`UrlService` is the principal business boundary: `src/main/java/com/sujay/urlshortener/service/UrlService.java` and `src/main/java/com/sujay/urlshortener/service/impl/UrlServiceImpl.java`. On creation, it derives a code through the short-code abstraction (`src/main/java/com/sujay/urlshortener/shortcode/ShortCodeGenerator.java`, `src/main/java/com/sujay/urlshortener/shortcode/SqidsShortCodeGenerator.java`), calculates expiration (`src/main/java/com/sujay/urlshortener/util/ExpiryCalculator.java`), and persists a `Url` record through `src/main/java/com/sujay/urlshortener/repository/UrlRepository.java`. Expiry behavior is modeled by `src/main/java/com/sujay/urlshortener/enums/ExpiryOption.java`.

#### Persistence and Cache Read Path
The durable URL model is `src/main/java/com/sujay/urlshortener/entity/Url.java`, backed by the repository layer. Redis is configured at `src/main/java/com/sujay/urlshortener/Config/RedisConfig.java` and accessed through `src/main/java/com/sujay/urlshortener/cache/service/RedisCacheService.java`. The expected redirect path is cache-first, with persisted lookup as the fallback; cached URL representation is `src/main/java/com/sujay/urlshortener/cache/model/CachedUrl.java`. This creates a clear boundary between low-latency resolution state and durable URL records.

#### Analytics and Background Processing
Redirect activity is accumulated via `src/main/java/com/sujay/urlshortener/cache/service/AnalyticsCacheService.java`, then periodically persisted by `src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java`. Scheduling is separated into `src/main/java/com/sujay/urlshortener/scheduler/AnalyticsFlushScheduler.java` and `src/main/java/com/sujay/urlshortener/scheduler/ExpiredUrlScheduler.java`; the latter drives cleanup through `src/main/java/com/sujay/urlshortener/service/CleanupService.java`. This decouples redirect latency from analytics writes and expired-record maintenance.

#### Failure, Health, and Observability
Domain failures distinguish missing codes from expired URLs through `src/main/java/com/sujay/urlshortener/exception/ShortUrlNotFoundException.java` and `src/main/java/com/sujay/urlshortener/exception/UrlExpiredException.java`; `src/main/java/com/sujay/urlshortener/exception/GlobalExceptionHandler.java` maps them to HTTP errors. Operational endpoints/checks and cache metrics are implemented in `src/main/java/com/sujay/urlshortener/health/HealthCheck.java` and `src/main/java/com/sujay/urlshortener/metrics/MetricsService.java`.

#### Infrastructure and Load Characteristics
The service depends on Redis for caching and buffered analytics, with connection settings provided by application configuration classes. `docker-compose.yml` and `prometheus/prometheus.yml` indicate containerized local infrastructure and Prometheus scraping. Load scenarios target the two core traffic modes—URL creation and redirect resolution—in `load-test/create-url.js` and `load-test/redirect.js`.

Main entry points: [`src/main/java/com/sujay/urlshortener/service/UrlService.java`](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/UrlService.java) (URL service), [`src/main/java/com/sujay/urlshortener/controller/UrlController.java`](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/controller/UrlController.java) (URL controller), [`src/main/java/com/sujay/urlshortener/repository/UrlRepository.java`](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/repository/UrlRepository.java) (URL repository), [`src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java`](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java) (Analytics flush service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_http["HTTP boundary"]
  node_url_controller["URL controller<br/>HTTP controller<br/>[UrlController.java]"]
  node_home_controller["Home controller<br/>HTTP controller"]
  node_dto["API DTOs<br/>HTTP contract"]
  node_exception_handler["Global exception handler<br/>error mapping"]
end

subgraph group_core["URL lifecycle"]
  node_url_service["URL service<br/>business service<br/>[UrlService.java]"]
  node_short_code["Short-code generator<br/>code generation"]
  node_expiry["Expiry calculation<br/>lifecycle policy"]
end

subgraph group_data["Storage &amp; cache"]
  node_url_repository["URL repository<br/>persistence adapter<br/>[UrlRepository.java]"]
  node_url_entity[("URL records<br/>durable model<br/>[Url.java]")]
  node_redis_cache["Redis cache service<br/>cache adapter"]
  node_redis[("Redis<br/>cache and counter store")]
  node_analytics_cache["Analytics cache service<br/>analytics buffer"]
end

subgraph group_background["Background processing"]
  node_analytics_flush["Analytics flush service<br/>analytics persistence"]
  node_analytics_scheduler["Analytics flush scheduler<br/>scheduled job"]
  node_expiry_scheduler["Expired URL scheduler<br/>scheduled job"]
  node_cleanup_service["Cleanup service<br/>maintenance service"]
end

subgraph group_operations["Operations"]
  node_health["Health checks<br/>operational endpoint<br/>[HealthCheck.java]"]
  node_metrics["Metrics service<br/>observability"]
  node_prometheus["Prometheus<br/>metrics scraper<br/>[prometheus.yml]"]
end

node_app{{"Spring Boot application<br/>runtime"}}

node_app -->|"starts"| node_url_controller
node_app -->|"starts"| node_home_controller
node_url_controller -->|"uses"| node_dto
node_url_controller -->|"create, resolve, stats"| node_url_service
node_url_controller -.->|"errors handled by"| node_exception_handler
node_url_service -->|"generates code"| node_short_code
node_url_service -->|"calculates expiry"| node_expiry
node_url_service -->|"cache-first resolution"| node_redis_cache
node_redis_cache -->|"reads and writes"| node_redis
node_url_service -->|"fallback and persistence"| node_url_repository
node_url_repository -->|"stores"| node_url_entity
node_url_service -->|"records redirects"| node_analytics_cache
node_analytics_cache -->|"buffers counters"| node_redis
node_analytics_scheduler -->|"triggers"| node_analytics_flush
node_analytics_flush -->|"drains"| node_analytics_cache
node_analytics_flush -->|"persists usage"| node_url_repository
node_expiry_scheduler -->|"triggers"| node_cleanup_service
node_cleanup_service -->|"removes expired records"| node_url_repository
node_health -.->|"checks"| node_redis
node_metrics -.->|"collects cache metrics"| node_redis
node_prometheus -->|"scrapes"| node_metrics

click node_app "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/UrlShortenerApplication.java"
click node_url_controller "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/controller/UrlController.java"
click node_home_controller "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/controller/HomeController.java"
click node_dto "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/dto/request/ShortenUrlRequest.java"
click node_exception_handler "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/exception/GlobalExceptionHandler.java"
click node_url_service "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/UrlService.java"
click node_short_code "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/shortcode/ShortCodeGenerator.java"
click node_expiry "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/util/ExpiryCalculator.java"
click node_url_repository "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/repository/UrlRepository.java"
click node_url_entity "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/entity/Url.java"
click node_redis_cache "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/cache/service/RedisCacheService.java"
click node_analytics_cache "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/cache/service/AnalyticsCacheService.java"
click node_analytics_flush "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java"
click node_analytics_scheduler "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/scheduler/AnalyticsFlushScheduler.java"
click node_expiry_scheduler "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/scheduler/ExpiredUrlScheduler.java"
click node_cleanup_service "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/CleanupService.java"
click node_health "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/health/HealthCheck.java"
click node_metrics "https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/metrics/MetricsService.java"
click node_prometheus "https://github.com/sujaydevx/url-shortner/blob/main/prometheus/prometheus.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_url_controller,node_home_controller,node_dto,node_exception_handler toneBlue
class node_url_service,node_short_code,node_expiry toneAmber
class node_url_repository,node_url_entity,node_redis_cache,node_redis,node_analytics_cache toneMint
class node_analytics_flush,node_analytics_scheduler,node_expiry_scheduler,node_cleanup_service toneRose
class node_health,node_metrics,node_prometheus toneIndigo
class node_app toneNeutral
```

## Components

### HTTP boundary

- [URL controller](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/controller/UrlController.java): HTTP controller · Handles shortening, redirects, and URL statistics. · `src/main/java/com/sujay/urlshortener/controller/UrlController.java`
- [Home controller](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/controller/HomeController.java): HTTP controller · `src/main/java/com/sujay/urlshortener/controller/HomeController.java`
- [API DTOs](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/dto/request/ShortenUrlRequest.java): HTTP contract · `src/main/java/com/sujay/urlshortener/dto/request/ShortenUrlRequest.java`
- [Global exception handler](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/exception/GlobalExceptionHandler.java): error mapping · Maps missing and expired URL failures to HTTP errors. · `src/main/java/com/sujay/urlshortener/exception/GlobalExceptionHandler.java`

### URL lifecycle

- [URL service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/UrlService.java): business service · Creates, resolves, and retrieves URL statistics. · `src/main/java/com/sujay/urlshortener/service/UrlService.java`
- [Short-code generator](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/shortcode/ShortCodeGenerator.java): code generation · `src/main/java/com/sujay/urlshortener/shortcode/ShortCodeGenerator.java`
- [Expiry calculation](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/util/ExpiryCalculator.java): lifecycle policy · `src/main/java/com/sujay/urlshortener/util/ExpiryCalculator.java`

### Storage & cache

- [URL repository](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/repository/UrlRepository.java): persistence adapter · `src/main/java/com/sujay/urlshortener/repository/UrlRepository.java`
- [URL records](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/entity/Url.java): durable model · Stores destination, short code, expiry, and usage state. · `src/main/java/com/sujay/urlshortener/entity/Url.java`
- [Redis cache service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/cache/service/RedisCacheService.java): cache adapter · Serves cached URL resolution records. · `src/main/java/com/sujay/urlshortener/cache/service/RedisCacheService.java`
- **Redis**: cache and counter store · Holds resolution cache and buffered analytics.
- [Analytics cache service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/cache/service/AnalyticsCacheService.java): analytics buffer · Accumulates redirect activity outside the request write path. · `src/main/java/com/sujay/urlshortener/cache/service/AnalyticsCacheService.java`

### Background processing

- [Analytics flush service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java): analytics persistence · `src/main/java/com/sujay/urlshortener/service/AnalyticsFlushService.java`
- [Analytics flush scheduler](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/scheduler/AnalyticsFlushScheduler.java): scheduled job · `src/main/java/com/sujay/urlshortener/scheduler/AnalyticsFlushScheduler.java`
- [Expired URL scheduler](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/scheduler/ExpiredUrlScheduler.java): scheduled job · `src/main/java/com/sujay/urlshortener/scheduler/ExpiredUrlScheduler.java`
- [Cleanup service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/service/CleanupService.java): maintenance service · `src/main/java/com/sujay/urlshortener/service/CleanupService.java`

### Operations

- [Health checks](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/health/HealthCheck.java): operational endpoint · `src/main/java/com/sujay/urlshortener/health/HealthCheck.java`
- [Metrics service](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/metrics/MetricsService.java): observability · Publishes cache metrics for operational monitoring. · `src/main/java/com/sujay/urlshortener/metrics/MetricsService.java`
- [Prometheus](https://github.com/sujaydevx/url-shortner/blob/main/prometheus/prometheus.yml): metrics scraper · `prometheus/prometheus.yml`

### Other components

- [Spring Boot application](https://github.com/sujaydevx/url-shortner/blob/main/src/main/java/com/sujay/urlshortener/UrlShortenerApplication.java): runtime · `src/main/java/com/sujay/urlshortener/UrlShortenerApplication.java`

## Connections

- Spring Boot application → URL controller: starts
- Spring Boot application → Home controller: starts
- URL controller → API DTOs: uses
- URL controller → URL service: create, resolve, stats
- URL controller → Global exception handler: errors handled by
- URL service → Short-code generator: generates code
- URL service → Expiry calculation: calculates expiry
- URL service → Redis cache service: cache-first resolution
- Redis cache service → Redis: reads and writes
- URL service → URL repository: fallback and persistence
- URL repository → URL records: stores
- URL service → Analytics cache service: records redirects
- Analytics cache service → Redis: buffers counters
- Analytics flush scheduler → Analytics flush service: triggers
- Analytics flush service → Analytics cache service: drains
- Analytics flush service → URL repository: persists usage
- Expired URL scheduler → Cleanup service: triggers
- Cleanup service → URL repository: removes expired records
- Health checks → Redis: checks
- Metrics service → Redis: collects cache metrics
- Prometheus → Metrics service: scrapes
