A robust, production-ready URL Shortener service built with Go (Golang). It features a clean architecture, Docker support, comprehensive testing (Unit & E2E), and CI/CD integration.
- Shorten URLs: Create short aliases for long URLs.
- Redirection: Fast redirection (307 Temporary Redirect) to the original URL.
- Custom Aliases: User can specify a custom alias or let the service generate a random one.
- Authentication: Usage is protected via Basic Auth.
- Persistent Storage: Utilizes SQLite for data persistence.
- Dockerized: Fully containerized for easy development and deployment.
- Tests: Covered by Unit tests and E2E functional tests.
- Language: Go 1.25+
- Database: SQLite3
- Router: Standard
net/httpServeMux - Validation:
go-playground/validator - Logging:
slog(Structured Logging)
- Go 1.25+
- Docker & Docker Compose (optional, for containerized run)
- Make (optional, for using Makefile commands)
Clone the repository and install dependencies:
git clone https://github.com/yourusername/url-shortener.git
cd url-shortener
go mod downloadRunning the application:
You can run the application directly on your machine. It will use a local storage.db file.
make runOr manually: go run cmd/url-shortener/main.go
The server will start at http://localhost:8080 (default).
The project includes both Unit and Integration (E2E) tests.
-
Run Unit Tests:
make test -
Run E2E Tests: This launches the application in a separate process and tests it as a black box using
httpexpect.make test-e2e
To run the application in a production-like environment using Docker:
# 1. Create .env file
cp .env.example .env
# 2. Build and Start
make docker-upThe API will be available at http://localhost:8080.
To stop the container:
make docker-downThis project supports a modern containerized deployment workflow.
To deploy updates, first build and push the Docker image to your registry (e.g., Docker Hub).
Ensure you are logged in (docker login).
export DOCKER_USERNAME={username}
make publishThis will build {username}/url-shortener:latest and push it to Docker Hub.
On your production server:
- Copy
docker-compose.prod.ymland rename it todocker-compose.yml. - Create a
.envfile with your production secrets. - Run the application:
# Pull the latest image and start
export DOCKER_IMAGE={docker-image}
docker compose pull && docker compose up -dAuth: Basic Auth is required for creates. Default: admin / admin.
POST /url
Request Body:
{
"url": "https://google.com",
"alias": "google" // Optional. If omitted, random alias is generated.
}Response (200 OK):
{
"status": "OK",
"alias": "google"
}GET /{alias}
Response:
307 Temporary Redirectto the original URL.404 Not Foundif alias does not exist.
.
├── cmd/ # Main applications
│ └── url-shortener # Entry point
├── internal/ # Private application logic
│ ├── config/ # Configuration loading
│ ├── server/ # HTTP server and handlers
│ │ ├── handler/ # API handlers & business logic
│ │ └── middleware/ # HTTP middlewares (Auth, Logger, etc)
│ ├── storage/ # Storage interfaces & implementation (SQLite)
│ └── lib/ # Shared utilities
├── tests/ # End-to-End tests
├── Dockerfile # Multi-stage build definition
├── docker-compose.yml # Local dev environment
└── Makefile # Make commands