A lightweight URL shortener service built with Go and Gin, supporting both SQLite and PostgreSQL databases.
  • Go 50.7%
  • HTML 49.3%
Find a file
Jimmy Berglund 770e7782ba
All checks were successful
CI / test (push) Successful in 3m41s
Add click handler for dynamically created copy buttons
2026-04-19 16:44:15 +02:00
.forgejo/workflows Removed build step 2026-04-18 19:28:18 +02:00
config Use SCREAMING_SNAKE_CASE for all config env vars 2026-04-19 14:43:08 +02:00
db Use SCREAMING_SNAKE_CASE for all config env vars 2026-04-19 14:43:08 +02:00
geoip Rename middleware to utils 2026-04-18 18:47:20 +02:00
handlers Fix HTTPS detection behind reverse proxy, add short URL to list, fix zero clicks 2026-04-19 15:57:45 +02:00
models Add index on short_code column 2026-04-19 14:29:31 +02:00
routes Add embedded UI with shorten form, URL list, and stats charts 2026-04-19 14:23:28 +02:00
services Use SCREAMING_SNAKE_CASE for all config env vars 2026-04-19 14:43:08 +02:00
templates Add click handler for dynamically created copy buttons 2026-04-19 16:44:15 +02:00
utils Add configurable logging level 2026-04-18 18:59:03 +02:00
.env.example Use SCREAMING_SNAKE_CASE for all config env vars 2026-04-19 14:43:08 +02:00
.gitignore Update .env.example with GeoIP options and add .mmdb to gitignore 2026-04-18 18:15:45 +02:00
go.mod Add GeoIP and timeline stats 2026-04-18 18:15:06 +02:00
go.sum Add GeoIP and timeline stats 2026-04-18 18:15:06 +02:00
LICENSE Add MIT license 2026-04-18 19:00:26 +02:00
main.go Use SCREAMING_SNAKE_CASE for all config env vars 2026-04-19 14:43:08 +02:00
README.md Update README: add demo instance, delete endpoint, fix config vars 2026-04-19 15:05:02 +02:00

URL Shortener

Go License

A lightweight URL shortener service built with Go and Gin, supporting both SQLite and PostgreSQL databases.

Demo Instance: https://s.jimmy-b.se

Features

  • Multiple Database Support - Switch between SQLite (development) and PostgreSQL (production) via configuration
  • Dynamic Short Codes - Auto-expanding code length to handle collision probability
  • Token-Based Auth - Each shortened URL has a unique token for accessing statistics
  • Click Tracking - Records every click with timestamp and geographic data
  • GeoIP Support - Country/city tracking via DB-IP database (optional)
  • Configurable Logging - Control log verbosity (silent/warn/error/info)

API Endpoints

Create Short URL

POST /api/shorten
Content-Type: application/json

{"url": "https://example.com"}

Response:

{
  "short_code": "abc123",
  "original_url": "https://example.com",
  "short_url": "https://yourdomain.com/abc123",
  "token": "550e8400-e29b-41d4-a716-446655440000"
}

Redirect

GET /abc123

Get Stats (requires token)

GET /api/stats/abc123
X-Token: 550e8400-e29b-41d4-a716-446655440000

Response:

{
  "short_code": "abc123",
  "original_url": "https://example.com",
  "total_clicks": 42,
  "countries": [
    {"country": "US", "count": 20},
    {"country": "SE", "count": 15},
    {"country": "DE", "count": 7}
  ],
  "timeline": [
    {"date": "2026-04-18", "count": 35},
    {"date": "2026-04-17", "count": 7}
  ],
  "attribution": "<a href='https://db-ip.com'>IP Geolocation by DB-IP</a>"
}

Delete URL (requires token)

DELETE /api/delete/abc123
X-Token: 550e8400-e29b-41d4-a716-446655440000

Configuration

Copy .env.example to .env and configure:

DB_TYPE=sqlite
SQLITE_PATH=./url_shortener.db
APP_PORT=8080
LOG_LEVEL=info
GIN_MODE=debug

# For PostgreSQL:
# DB_TYPE=postgres
# POSTGRES_URL=postgresql://user:password@localhost:5432/dbname

# GeoIP (optional):
# GEOIP_ENABLED=true
# GEOIP_DB_PATH=./geoip.mmdb
# GEOIP_URL=https://download.db-ip.com/free/dbip-city-lite-2026-04.mmdb.gz

Getting Started

# Install dependencies
go mod tidy

# Run the server
go run .

Testing

# Run all tests
go test ./... -v

Architecture

├── config/     - Configuration loading
├── models/     - Database models (URL, Stat)
├── db/         - Database layer (GORM)
├── services/   - Business logic
├── handlers/   - HTTP request handling
├── routes/    - Route registration
├── geoip/     - GeoIP integration
└── utils/     - Utility functions

Tech Stack

  • Go - Programming language
  • Gin - HTTP web framework
  • GORM - Database ORM
  • SQLite - Development database
  • PostgreSQL - Production database

License

MIT