URL shorteners are everywhere, from social media to analytics platforms. They look simple, but under the hood, they require careful thought: idempotency, collision management, fast lookups, and clean API design.
I recently completed the URL Shortener challenge from Coding Challenges, and although it seems like a tiny project on the surface, it turned into a rich learning experience.
In this article, I walk you through how I built a lightweight, fast, and reliable URL Shortener using:
- Go
- Redis(Memurai on Windows)
Why I Chose Go + Redis
I built the project using:
- Go for its simplicity, speed, and clean standard library
- Redis as an in-memory key–value store for O(1) lookups
- A very small project structure with separate handlers and utilities
What the Service Does
The service exposes two endpoints:
POST /shorten
Accepts a long URL and returns a short one.GET /{shortCode}
Redirects the user to the original URL.
The project structure looks like this:
url-shortner/
├─ config/
│ └─ redis.go
├─ handlers/
│ ├─ shorten.go
│ └─ redirect.go
├─ utils/
│ └─ hash.go
├─ main.go
├─ go.mod
└─ go.sum
How It Works
1. Shortening URLs
The ShortenHandlerin handlers/shorten.go handles POST requests to /shorten. The workflow is as follows:
-
Receive request – The API expects a JSON payload with the
URLfield. - Check for existing mapping – If the long URL already exists in Redis, the same short URL is returned (ensuring idempotency).
- Generate a shortcode – A random alphanumeric code of 6 characters is generated. If a collision occurs, a salted SHA1 hash ensures uniqueness.
- Store mappings – The short code maps to the long URL, and a reverse mapping is also stored for idempotency.
Example request:
POST /shorten
{
"url": "https://example.com/very-long-url"
}
Response:
{
"short_url": "http://localhost:8080/aB9xYz"
}
2. Redirecting Short URLs
The RedirectHandlerin handlers/redirect.go handles GET requests for short URLs:
- Extract the short code from the request path.
- Look up the original URL in Redis.
- Redirect the client to the long URL using HTTP status
302 Found.
3. Generating Short Codes
utils/hash.go provides two functions:
- GenerateShortCode(n int) – Generates a random alphanumeric code.
- GenerateShortCodeWithSalt(url string) – Uses SHA1 hashing and the current timestamp as a salt to avoid collisions in case of duplicates.
Redis Integration
config/redis.go sets up the Redis client:
- Connects to Redis at
localhost:6379. - Pings the server to ensure connectivity.
- Provides a global
RedisClientandCtxfor use across the project.
Redis stores:
- shortCode → longURL(for redirecting)
- longURL → shortCode (for idempotent shortening)
Here’s the full implementation on GitHub
Key Features
- Idempotent URL shortening – Multiple requests for the same long URL return the same short URL.
- Collision handling – Ensures unique short codes.
- Fast in-memory storage – Using Redis for near-instant lookups.
- Simple API – Minimalist design for ease of use.
Future Enhancements
- Add analytics to track URL clicks.
- Implement custom short codes for user-defined aliases.
- Add expiration time for temporary links.
Top comments (0)