Alcides Oliveira

Full-stack software engineer

All projects

URL Shortener

Side project · Sep 2026 · Source code

A small, complete app built around Angular and Spring Boot. You paste a long URL, get a short one back, and the API redirects anyone who opens it.

I built it alone.

URL Shortener, screenshot 1
The Angular page: a URL field and the Shorten Url button.

I wanted a small app that covers the whole path of a web request: a field in the browser, a REST API, and a relational database. A URL shortener has that shape, with one table and two endpoints.

A DTO and mapper in a small app

The first working version passed the entity between layers. Once the controller, service, and database worked, I added a record DTO and a MapStruct mapper, so the API contract is separate from the table. For one table this adds files, and it keeps the persistence model out of the HTTP layer.

Four random letters as the code

The service generates four random lowercase letters, which gives short, readable links and 456,976 possible codes. The trade-off is collisions: the database rejects a duplicate code through the unique constraint, but the service does not retry yet, and the README says so.

Schema managed by Hibernate

I let Hibernate create the table with ddl-auto=update instead of writing migrations. With one table and no deployed data, setup comes down to one CREATE DATABASE, at the cost of no versioned schema history.

  • A Spring Boot 4 REST API in Java 17 with two endpoints: one that creates a short code and one that redirects with 302 or returns 404.
  • A JPA entity and a Spring Data repository with a derived query that finds a link by its code, backed by a unique constraint on the code column in PostgreSQL.
  • A Java record as the DTO and a MapStruct mapper between it and the entity, so the controller receives and returns the DTO and never the persistence model.
  • Code generation with Apache Commons Text’s RandomStringGenerator and a scheme check that prefixes https:// to bare addresses.
  • An Angular 21 component that posts the address with HttpClient and shows the result through a signal, styled with Tailwind CSS 4.
  • A README that documents setup, endpoints, configuration, tests, and the current limits of the app.

The Angular page binds the typed address to a text field with ngModel. When the user clicks Shorten Url, HttpClient sends it to POST /urlshortener/post. The Spring Boot service adds https:// when the address has no scheme, generates a four-letter lowercase code with Apache Commons Text, and saves the address and the code through Spring Data JPA into a PostgreSQL table. The API answers 201 Created with the id, the saved URL, and the code.

The page joins the back-end address with the returned code, stores the full link in an Angular signal, and shows it under the field. Opening that link hits GET /urlshortener/{code}. The service looks up the code through the repository, and the controller answers 302 Found with a Location header pointing to the original URL, or 404 Not Found when the code does not exist.

Hibernate creates or updates the table on startup. The database password comes from an environment variable, and Spring’s standard environment variables can override the connection URL and username. The controller allows cross-origin requests from the local Angular dev server.

Front end
Angular 21, TypeScript 5.9, Angular signals, HttpClient, Tailwind CSS 4
Back end
Java 17, Spring Boot 4.1, Spring Web MVC, Spring Data JPA, Hibernate, MapStruct, Lombok, Apache Commons Text
Data
PostgreSQL
Tooling
Maven, npm, Vitest, Prettier