This project is a beginner-friendly URL shortener built with Rust, Axum, and MySQL. It focuses on the essentials: create a short link, redirect to the original URL, and fetch basic stats.
- POST /shorten to create a short link
- GET /{short_code} to redirect
- GET /stats/{short_code} to view clicks and created time
- GET /health to verify the database connection
- Rust (latest stable)
- MySQL Server
CREATE DATABASE url_shortener_db;Create a .env file in the project root:
DATABASE_URL=mysql://username:password@localhost:3306/url_shortener_db
SERVER_HOST=127.0.0.1
SERVER_PORT=3000
RUST_LOG=debug,tower_http=debug,axum=debugcargo build
cargo runServer starts at http://127.0.0.1:3000
GET http://127.0.0.1:3000/healthPOST http://127.0.0.1:3000/shorten
Content-Type: application/json
{
"url": "https://www.example.com/very/long/url/that/needs/shortening"
}Response example:
{
"short_code": "abc1234",
"short_url": "http://127.0.0.1:3000/abc1234",
"original_url": "https://www.example.com/very/long/url/that/needs/shortening"
}GET http://127.0.0.1:3000/{short_code}GET http://127.0.0.1:3000/stats/{short_code}Response example:
{
"short_code": "abc1234",
"original_url": "https://www.example.com/very/long/url/that/needs/shortening",
"clicks": 3,
"created_at": "2026-02-10T18:23:45"
}- main.rs starts the server and prepares shared state.
- database.rs connects to MySQL and ensures the urls table exists.
- routes.rs defines the handlers and SQL queries.
The app creates this table automatically if it does not exist:
CREATE TABLE urls (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
short_code VARCHAR(10) UNIQUE NOT NULL,
original_url TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
clicks INT DEFAULT 0
);