Skip to content

chintanchhapgar/Core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

49 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ShopSphere Banner

πŸ”— URL Shortener API

Enterprise-grade URL Shortening REST API β€” ASP.NET Core 8 Β· Clean Architecture Β· CQRS Β· MediatR Β· EF Core Β· JWT Β· Serilog Β· GitHub Actions

Build Status Β  License Β  Last Commit Β  Repo Size


Table of Contents


Overview

The URL Shortener API is a production-ready, enterprise-grade RESTful service built with ASP.NET Core 8, following Clean Architecture, CQRS, and Domain-Driven Design principles.

This project serves as a comprehensive reference implementation demonstrating modern backend engineering practices β€” from JWT Authentication and CQRS with MediatR, to distributed caching, background services, comprehensive integration testing, and automated CI/CD pipelines.


Key Features

Domain Capabilities
Authentication & Identity JWT Bearer Tokens Β· User Registration Β· User Login Β· Protected Endpoints Β· Claims-based Access
URL Management Create Short URLs Β· Custom Aliases Β· Update URLs Β· Delete URLs Β· URL Expiration
URL Lifecycle Activate URLs Β· Deactivate URLs Β· User-specific URL Management
Redirect Engine Fast URL Resolution Β· Click Tracking Β· Visit Logging Β· Expiry & Status Validation
Analytics Total Click Count Β· Browser Statistics Β· OS Statistics Β· Recent Visits Β· Analytics Caching
Performance In-Memory Cache Β· URL Cache Β· Analytics Cache Β· Optimized Queries Β· Pagination
Reliability Health Checks Β· Background Cleanup Service Β· Global Exception Handling Β· Correlation IDs
Observability Serilog Structured Logging Β· Health Endpoints Β· Rate Limiting
Testing 29+ Integration Tests Β· xUnit Β· FluentAssertions Β· SQLite In-Memory Testing
DevOps GitHub Actions CI Β· Automated Build, Restore & Test Pipeline

Architecture

The system strictly adheres to Clean Architecture with enforced layer boundaries and a unidirectional dependency rule.

flowchart TD
    Client["🌐 Client / Browser"]
    API["βš™οΈ API Layer\nControllers Β· Middleware Β· Auth"]
    APP["πŸ“‹ Application Layer\nCQRS Β· MediatR Β· Validation Β· Use Cases"]
    DOMAIN["πŸ› Domain Layer\nEntities Β· Aggregates Β· Business Rules"]
    INFRA["πŸ”§ Infrastructure\nLogging Β· Caching Β· Background Services"]
    PERSIST["πŸ—ƒ Persistence\nEF Core Β· Repositories Β· Unit of Work"]
    DB[("πŸ—„οΈ SQL Server / SQLite")]

    Client --> API
    API --> APP
    APP --> DOMAIN
    APP --> INFRA
    APP --> PERSIST
    PERSIST --> DB

    classDef api fill:#2563EB,color:#ffffff,stroke:#1E40AF,stroke-width:2px
    classDef app fill:#059669,color:#ffffff,stroke:#047857,stroke-width:2px
    classDef domain fill:#7C3AED,color:#ffffff,stroke:#6D28D9,stroke-width:2px
    classDef infra fill:#EA580C,color:#ffffff,stroke:#C2410C,stroke-width:2px
    classDef db fill:#1F2937,color:#ffffff,stroke:#111827,stroke-width:2px

    class API api
    class APP app
    class DOMAIN domain
    class INFRA,PERSIST infra
    class DB db
Loading

Request Flow

flowchart TD
    A["🌐 Client"]
    B["πŸš€ API Endpoint\n(Controller)"]
    C["πŸ“¨ MediatR Dispatcher"]
    D["⚑ Command / Query"]
    E["🧠 Handler\n(Business Logic)"]
    F["πŸ“¦ Repository\n(Abstraction)"]
    G["πŸ”§ Entity Framework Core"]
    H[("πŸ’Ύ Database")]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    G --> H

    classDef api fill:#2563EB,color:#ffffff,stroke:#1E40AF,stroke-width:2px
    classDef app fill:#059669,color:#ffffff,stroke:#047857,stroke-width:2px
    classDef infra fill:#EA580C,color:#ffffff,stroke:#C2410C,stroke-width:2px
    classDef db fill:#7C3AED,color:#ffffff,stroke:#6D28D9,stroke-width:2px

    class B api
    class C,D,E app
    class F,G infra
    class H db
Loading

Dependency Rule: Dependencies flow strictly inward. The Domain layer has zero external dependencies. Application depends only on Domain. Infrastructure and Persistence depend on Application β€” never the reverse.


Solution Structure

UrlShortener/
β”‚
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ UrlShortener.API              # Presentation β€” Controllers, Middleware, Configuration
β”‚   β”œβ”€β”€ UrlShortener.Application      # Use Cases β€” CQRS Commands, Queries, Handlers, Validators
β”‚   β”œβ”€β”€ UrlShortener.Domain           # Core Business β€” Entities, Aggregates, Domain Rules
β”‚   β”œβ”€β”€ UrlShortener.Infrastructure   # Cross-cutting β€” Logging, Caching, Background Services
β”‚   └── UrlShortener.Persistence      # Data β€” EF Core Context, Repositories, Migrations
β”‚
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ UrlShortener.UnitTests        # Domain & Business Logic Tests
β”‚   └── UrlShortener.IntegrationTests # End-to-End API Tests (SQLite In-Memory)
β”‚
└── UrlShortener.sln

Technology Stack

Category Technology
Framework ASP.NET Core 8
Language C# 12
ORM Entity Framework Core 8
Database SQL Server / SQLite
Architecture Clean Architecture
Design Patterns CQRS Β· MediatR Β· Repository Β· Unit of Work
Authentication ASP.NET Identity Β· JWT Bearer
Validation FluentValidation
Logging Serilog
Caching IMemoryCache
Background Services .NET Hosted Services
API Documentation Swagger / OpenAPI
Testing xUnit Β· FluentAssertions Β· SQLite In-Memory
CI/CD GitHub Actions

API Endpoints

Authentication

Method Endpoint Description
POST /api/auth/register Register a new user account
POST /api/auth/login Authenticate and receive JWT token

URL Management

Method Endpoint Description
POST /api/urls Create a new shortened URL
GET /api/urls Retrieve all URLs for authenticated user
PUT /api/urls/{id} Update an existing URL
DELETE /api/urls/{id} Delete a URL permanently
PUT /api/urls/{id}/activate Activate a deactivated URL
PUT /api/urls/{id}/deactivate Deactivate an active URL
GET /api/urls/{id}/analytics Retrieve analytics for a specific URL

Redirect

Method Endpoint Description
GET /{shortCode} Resolve and redirect to the original URL

Health

Method Endpoint Description
GET /health Returns system health status

Security

  • βœ… JWT Bearer Token Authentication
  • βœ… Claims-based Authorization Policies
  • βœ… Secure Password Hashing (ASP.NET Identity)
  • βœ… Protected Endpoints with [Authorize]
  • βœ… API Rate Limiting to prevent abuse
  • βœ… Secure Middleware Pipeline
  • βœ… Global Exception Handling β€” no stack traces exposed

Performance

  • βœ… In-Memory URL Caching for fast redirect resolution
  • βœ… Analytics Result Caching to reduce database load
  • βœ… Background Cleanup Service for expired URL removal
  • βœ… Optimized EF Core Queries with AsNoTracking
  • βœ… Pagination support for large datasets

Health Checks

The application exposes a health endpoint for infrastructure monitoring:

GET /health
Check Description
Database Validates SQL Server / SQLite connectivity
Memory Monitors application memory pressure
Cache Validates IMemoryCache availability

Testing

The project includes a comprehensive automated test suite:

Type Count Coverage
Integration Tests 29+ Auth, CRUD, Redirect, Analytics, Health
Unit Tests β€” Domain Logic, Validators

Tests use SQLite In-Memory for fast, isolated database testing without external dependencies.

Run all tests:

dotnet test

Running Locally

1. Clone the Repository

git clone https://github.com/chintanchhapgar/core.git
cd UrlShortener

2. Restore Dependencies

dotnet restore

3. Build the Solution

dotnet build

4. Run the API

dotnet run --project src/UrlShortener.API

5. Access Swagger UI

https://localhost:5001/swagger

Configuration

Update appsettings.json with your environment values:

{
  "ConnectionStrings": {
    "DefaultConnection": "Your_Database_Connection_String"
  },
  "Jwt": {
    "Issuer": "your-issuer",
    "Audience": "your-audience",
    "SecretKey": "your-secret-key-minimum-32-characters"
  },
  "Serilog": {
    "MinimumLevel": "Information"
  }
}

CI/CD

GitHub Actions automatically runs on every push and pull request:

flowchart LR
    A["πŸ“¦ Push / PR"] --> B["πŸ”„ Restore Packages"]
    B --> C["πŸ”¨ Build Solution"]
    C --> D["πŸ§ͺ Run All Tests"]
    D --> E{"βœ… Pass / ❌ Fail"}
Loading
Step Description
Restore Restores all NuGet packages
Build Compiles the entire solution
Test Executes all unit and integration tests

Screenshots

Swagger UI
Swagger API Documentation


Health Check
System Health Monitoring


Analytics
URL Analytics Dashboard


GitHub Actions
GitHub Actions CI/CD Pipeline


Roadmap

Feature Status
Docker Support πŸ“… Planned
Redis Distributed Cache πŸ“… Planned
Refresh Token Support πŸ“… Planned
PostgreSQL Support πŸ“… Planned
Azure Deployment πŸ“… Planned
Kubernetes Support πŸ“… Planned
OpenTelemetry Integration πŸ“… Planned
Prometheus Metrics πŸ“… Planned
Email Verification πŸ“… Planned

Engineering Practices

  • βœ… Clean Architecture with strict layer separation
  • βœ… CQRS Pattern (Commands & Queries via MediatR)
  • βœ… Repository & Unit of Work Pattern
  • βœ… Domain-Driven Design (DDD) concepts
  • βœ… Dependency Injection throughout
  • βœ… SOLID Principles
  • βœ… JWT Authentication & Authorization Policies
  • βœ… Background Services for automated cleanup
  • βœ… In-Memory Caching Strategy
  • βœ… Structured Logging & Observability (Serilog)
  • βœ… Global Exception Handling Middleware
  • βœ… API Rate Limiting
  • βœ… Health Check Endpoints
  • βœ… Integration & Unit Testing
  • βœ… Automated CI/CD via GitHub Actions

License

This project is licensed under the MIT License β€” see the LICENSE file for details.


Author

Chintan Chhapgar

Β 


Built with precision Β· Engineered for scale Β· Designed for clarity

About

Modern ASP.NET Core solutions showcasing Clean Architecture, REST APIs, authentication, Entity Framework Core, and enterprise development best practices.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages