← All projects

Backend exercise from a written brief · 2026

Short link service

An HTTP service that shortens URLs, redirects on lookup and counts how often each link is followed. No dependencies: Node's built-in HTTP server and SQLite.

Problem

A URL shortener looks trivial until you think about accurate counts, malicious links, repeated URLs and concurrent requests.

Context and motivation

A backend exercise where every decision had to be justified in writing.

What I built

Built on my own: API, storage, validation, tests and the written design decisions.

Technical decisions

4

302, not 301

Browsers may cache a 301 indefinitely: later clicks never reach the service, the count goes wrong, and a target that turns malicious can't be fixed. A 302 with Cache-Control: no-store costs one extra request per click — acceptable for a service whose job is to count.

Same URL, same code

URLs are normalised and a UNIQUE constraint stops two concurrent requests from creating two codes. An existing URL returns 200 with its original code; a new one returns 201.

Validate before storing

Only http and https with a host, up to 2,048 characters; javascript:, data: and file: are rejected. Request bodies are capped at 16 KB and codes are validated before they reach the database.

Atomic counting

UPDATE … SET hits = hits + 1 … RETURNING url looks up and increments in one statement, so parallel clicks are never lost (tested with 25 simultaneous requests).

What it does

  • POST /links, GET /:code and GET /links/:code
  • Random 7-character base62 codes, retried on collision
  • JSON errors with a requestId; a 500 never exposes the exception
  • One JSON log line per request (method, route, status, duration)

Evidence

what was checked, and how
WhatResultSourceChecked
Automated tests7 passednpm test run locally

Limitations and next steps

Known limitations

  • No authentication or rate limiting: anyone who can reach the service can create links.