Backend & APIs · Beginner
Shrtn: URL Shortener API
Build a REST API that turns long links into short codes, redirects on lookup, and counts clicks, with rate limiting and tests.
You will build a production-shaped URL shortener as a REST API: clients POST a long URL and receive a short code, then any GET request to that code is redirected to the original destination while a click counter increments in PostgreSQL. The project covers the full backend request lifecycle from routing and validation through database persistence and HTTP redirects. It is a compact but realistic scope that lets you practice REST design, relational data modeling, and test-driven development without getting lost in incidental complexity.
What you build
- POST /links accepts a long URL and returns a unique short code
- GET /:code performs a 302 redirect to the original URL and increments the click count
- GET /links/:code/stats returns the original URL, creation date, and total click count
- DELETE /links/:code removes a short link from the database
- Per-IP rate limiting rejects clients that exceed a configurable request threshold
- Input validation rejects malformed or non-HTTP URLs with a clear error response
- Vitest integration tests cover the happy path and key error cases for each endpoint
What it teaches
- Designing and implementing a REST API with clear resource naming and correct HTTP status codes
- Relational schema design and running schema migrations with an ORM
- Writing integration tests that hit real HTTP endpoints against a test database
- Implementing middleware for cross-cutting concerns such as rate limiting and input validation
- Generating short unique identifiers and handling collision detection in a database
- Reading and writing environment configuration safely using dotenv or Node's built-in env handling
How it works
- 1
Client
- POST /links {url}
- GET /:code
- 2
Hono Router
- Rate limit middleware
- Validate input
↓ Returns 429 or 422 on failure
- 3
Handler
- Generate code (POST)
- Lookup code (GET)
- 4
PostgreSQL via Drizzle
- INSERT link row
- SELECT + UPDATE clicks
- 5
Response
- 201 + short code
- 302 redirect to original URL
Sign in to open the build guide
Free account. Get the step-by-step build and every resource link.
Take it further
- Add a custom alias option to POST /links so callers can request a vanity code like `shrtn.me/my-brand`.
- Implement link expiry: accept an optional `expires_at` timestamp at creation and return 410 Gone after that date.
- Add a minimal HTML dashboard served at GET / that lists recent links and their click counts using Hono's JSX support.


