Hayrettin DalAdminTR|EN
blog/Vaka Çalışması

URL Shortener API: layered design and explicit technical limits

I separated URL shortening workflows from HTTP and persistence, while keeping the missing live demo, concurrency handling and CI evidence explicit.

Problem

I built a small API to store long URLs under short codes and redirect those codes to the original address. The aim was to separate validation, persistence and application logic into clear responsibilities.

My contribution

I implemented creation, lookup and HTTP 302 redirect endpoints with .NET 8 and ASP.NET Core. I separated Domain, Application, Infrastructure and API layers and organized CQRS workflows with MediatR. I added PostgreSQL/EF Core persistence, FluentValidation, xUnit/Moq tests, Docker Compose and structured logging.

Architecture

This diagram shows request flow and layer responsibilities.

POST /api/urls
  → API → Application: validation + MediatR handler
    → Domain: URL entity / repository contract
      → Infrastructure: EF Core → PostgreSQL

GET /r/{shortCode}
  → Query handler → found: HTTP 302
                    missing: HTTP 404

One decision and its tradeoff

I moved creation and lookup logic out of the controller into handlers and repository contracts. This makes workflows easier to test separately from HTTP and data access. It also adds files and dependency wiring for an API of this size.

Evidence

For the source review dated , inspectable evidence includes the public repository, 302 redirect controller and test sources. Test files do not demonstrate a current successful run; tests were not rerun for this work.

Limitations

There is no live demo. The rate-limit partition key falls back to Host for anonymous requests, leaving per-client separation incomplete. Checking a short code before saving it does not by itself resolve concurrent requests selecting the same code; retry after an insert collision is missing. CI setup/verification remains incomplete, with no successful CI result offered. These gaps were not fixed here.

Back to all projects

More writingView all writing