A lightweight, high-performance URL shortening service built with Go. ShortLink generates short, random codes for long URLs and provides instant redirects with in-memory storage.
- Fast & Lightweight: Built with Go's standard library, no external dependencies
- Secure Random Generation: Uses
crypto/randfor cryptographically secure short codes - Thread-Safe: Concurrent request handling with
sync.RWMutex - RESTful API: Clean JSON-based API endpoints
- URL Validation: Comprehensive validation for input URLs
- Collision Detection: Automatic retry mechanism for hash collisions
- Easy Testing: Includes automated test script and comprehensive test cases
- Go 1.25.5 or higher
- curl (for testing)
- jq (optional, for pretty JSON output)
url-shortener/
โโโ go.mod # Go module definition
โโโ main.go # Application entry point and server setup
โโโ handler.go # HTTP request handlers and routing logic
โโโ storage.go # In-memory storage with thread-safe operations
โโโ test.sh # Automated testing script
โโโ TESTING.md # Detailed testing documentation
โโโ README.md # This file
cd /path/to/url-shortenergo mod tidy# Build executable
go build -o url-shortener .
# Run the executable
./url-shortenerOr run directly without building:
go run .Start the server on port 8080:
go run .You should see:
URL Shortener server starting on http://localhost:8080
Endpoints:
POST /shorten - Create a short URL
GET /{shortCode} - Redirect to original URL
The server is now ready to accept requests!
Endpoint: POST /shorten
Request:
curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://www.google.com"}'Request Body:
{
"url": "https://www.example.com"
}Response (200 OK):
{
"short_url": "http://localhost:8080/a3at1M4"
}Error Responses:
400 Bad Request- Empty URL or invalid URL format405 Method Not Allowed- Wrong HTTP method500 Internal Server Error- Failed to generate unique code
Endpoint: GET /{shortCode}
Request:
curl -L http://localhost:8080/a3at1M4Response:
302 Found- Redirects to original URL404 Not Found- Short code doesn't exist405 Method Not Allowed- Wrong HTTP method
Example in Browser:
Simply visit http://localhost:8080/a3at1M4 and you'll be automatically redirected to the original URL.
Run the included test script that validates all functionality:
chmod +x test.sh
./test.shExpected Output:
=== Testing URL Shortener Backend ===
1. Creating short URL for https://www.google.com...
โ
Short code created: a3at1M4
2. Testing redirect (should return 302)...
โ
Redirect working (HTTP 302)
3. Testing empty URL validation...
โ
Empty URL validation working
4. Testing invalid URL validation...
โ
Invalid URL validation working
5. Testing non-existent short code (should return 404)...
โ
404 handling working
6. Testing wrong HTTP method (GET on /shorten)...
โ
Method not allowed handling working
=== All Tests Complete ===
curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://www.google.com"}'Expected Response:
{
"short_url": "http://localhost:8080/abc123"
}With Pretty Print (requires jq):
curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com"}' | jq .Test Redirect:
# Replace abc123 with your actual short code
curl -L http://localhost:8080/abc123Check Redirect Headers (without following):
curl -v http://localhost:8080/abc123 2>&1 | grep -i "location\|302"Expected: HTTP 302 Found with Location: https://www.google.com
Empty URL:
curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": ""}'Expected: URL is required (400 Bad Request)
Invalid URL Format:
curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "not-a-valid-url"}'Expected: Invalid URL format (400 Bad Request)
Non-existent Short Code:
curl http://localhost:8080/nonexistentExpected: Short URL not found (404 Not Found)
Wrong HTTP Method:
curl -X GET http://localhost:8080/shortenExpected: Method not allowed (405 Method Not Allowed)
# 1. Start the server (in one terminal)
go run .
# 2. Create a short URL (in another terminal)
SHORT_CODE=$(curl -s -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://www.example.com"}' | jq -r '.short_url' | cut -d'/' -f4)
echo "Short code: $SHORT_CODE"
# 3. Test the redirect
curl -I http://localhost:8080/$SHORT_CODE
# 4. Test error cases
echo "Testing empty URL..."
curl -s -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": ""}'
echo -e "\nTesting invalid URL..."
curl -s -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "invalid"}'
echo -e "\nTesting non-existent code..."
curl -s http://localhost:8080/doesnotexistIf you have httpie installed:
# Create short URL
http POST localhost:8080/shorten url=https://www.google.com
# Test redirect
http GET localhost:8080/abc123-
Create Short URL:
- Use a tool like Postman, Insomnia, or browser DevTools
- POST to
http://localhost:8080/shorten - Body:
{"url": "https://www.google.com"}
-
Test Redirect:
- Simply visit
http://localhost:8080/{shortCode}in your browser - You should be redirected to the original URL
- Simply visit
1. Storage Layer (storage.go)
- Thread-safe in-memory storage using
sync.RWMutex - Hash map for O(1) lookups:
shortCode โ originalURL - Collision detection on save operations
2. Handler Layer (handler.go)
- HTTP request handling and routing
- Input validation and sanitization
- Short code generation using crypto/rand
- Base62 encoding (0-9, a-z, A-Z) for compact codes
3. Application Layer (main.go)
- Server initialization and configuration
- Route registration
- Graceful error handling
- Length: 7 characters
- Character Set: Base62 (0-9, a-z, A-Z)
- Entropy: ~41.36 bits (62^7 = 3.5 trillion combinations)
- Algorithm: Cryptographically secure random generation
- Collision Handling: Up to 10 retries with new random codes
- Must have valid scheme (http/https)
- Must have valid host
- Uses Go's
net/urlpackage for parsing
- Input Validation: All URLs are validated before storage
- Secure Random: Uses
crypto/randfor unpredictable codes - Thread Safety: Mutex-protected concurrent access
- No SQL Injection: In-memory storage (no database)
- In-Memory Storage: Ultra-fast O(1) lookups and inserts
- Concurrent Safe: Multiple requests handled simultaneously
- No External Dependencies: Pure Go standard library
- Lightweight: Minimal memory footprint
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Short URL created successfully |
| 302 | Found | Redirecting to original URL |
| 400 | Bad Request | Invalid or empty URL |
| 404 | Not Found | Short code doesn't exist |
| 405 | Method Not Allowed | Wrong HTTP method used |
| 500 | Internal Server Error | Failed to generate unique code |
# Terminal 1: Start server
$ go run .
URL Shortener server starting on http://localhost:8080
Endpoints:
POST /shorten - Create a short URL
GET /{shortCode} - Redirect to original URL
# Terminal 2: Create short URLs
$ curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://www.google.com"}'
{"short_url":"http://localhost:8080/a3at1M4"}
$ curl -X POST http://localhost:8080/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com"}'
{"short_url":"http://localhost:8080/mxb0HlF"}
# Test redirects
$ curl -L http://localhost:8080/a3at1M4
# (Google homepage HTML)
$ curl -L http://localhost:8080/mxb0HlF
# (GitHub homepage HTML)./test.shgo build -o url-shortener .
./url-shortener- main.go: Server setup, route registration
- handler.go: Business logic, validation, code generation
- storage.go: Data persistence layer
- Persistent storage (Redis/PostgreSQL)
- Custom short code support
- Analytics and click tracking
- Expiration dates for URLs
- Rate limiting
- API authentication
- QR code generation
- Custom domains
- URL preview endpoint
- Admin dashboard
This project is open source and available for educational purposes.
Built with โค๏ธ using Go
Contributions, issues, and feature requests are welcome!
For issues or questions, please open an issue in the repository.
Happy URL Shortening! ๐