A lightweight URL shortener service built with Go and Gin, supporting both SQLite and PostgreSQL databases.
- Go 50.7%
- HTML 49.3%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| config | ||
| db | ||
| geoip | ||
| handlers | ||
| models | ||
| routes | ||
| services | ||
| templates | ||
| utils | ||
| .env.example | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| README.md | ||
URL Shortener
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