Ferris URL is a high-performance, asynchronous URL shortener and analytics service built with Rust. It leverages Axum for the web layer, PostgreSQL for persistent storage, and Redis for high-speed caching and real-time analytics buffering.
Designed with a production-ready architecture using the Model-Manager pattern, prioritizing security, speed, and clean code.
- Language: Rust (Edition 2021)
- Framework: Axum (Ergonomic and modular web framework)
- Database: PostgreSQL (via
sqlx) - Cache/Queue: Redis (via
redis-rs) - Auth: JWT (Json Web Tokens) in Secure Cookies + Argon2 Password Hashing
- Async Runtime: Tokio
- Serialization: Serde
- ⚡ High-Performance Redirects: Public redirects (
/:id) are served directly from Redis cache, bypassing the database for hot links. - 📊 Write-Behind Analytics: Visits are pushed to a Redis queue and asynchronously flushed to PostgreSQL in batches to prevent database bottlenecks during traffic spikes.
- 🛡️ Secure by Design:
- Argon2 password hashing.
- SQL Injection protection via
sqlbquery builder and parameter binding. - Secure Cookies (HTTP-only, Secure) for authentication.
- 🆔 Collision-Resistant IDs: Uses
nanoidwith a try-insert pattern to ensure unique short codes. - 🏗️ Modular Architecture: Clean separation of concerns:
src/web: HTTP handlers and routing.src/model: Database interactions and business logic.src/ctx: Request context and user identity.
Ensure you have the following installed:
- Rust & Cargo (v1.75+)
- PostgreSQL
- Redis
- SQLx CLI (Optional, for database setup)
git clone https://github.com/yourusername/ferris-url.git
cd ferris-urlCreate a .env file in the root directory. You must provide the following variables:
# .env
# App Configuration
DB_URL=postgres://postgres:password@localhost:5432/ferris_url
REDIS_URL=redis://127.0.0.1:6379/
SECRET_KEY=super-secret-key-for-jwt-signing
SECURE_COOKIE=true # Set to false for localhost testing without HTTPS
# Optional: For sqlx cli to work automatically
DATABASE_URL=postgres://postgres:password@localhost:5432/ferris_urlYou need to initialize the PostgreSQL database with the required tables. You can execute the SQL files located in the sql/ directory:
sql/01-user.sqlsql/02-urls.sqlsql/03-visits.sql
If using sqlx-cli:
# Create the database
sqlx database create
# Run migrations
sqlx migrate run --source sqlcargo runThe server will start on http://127.0.0.1:8080.
| Method | Endpoint | Description |
|---|---|---|
GET |
/:id |
Redirect: Redirects to the original URL (Cached & Tracked). |
POST |
/api/signup |
Register a new user. |
POST |
/api/login |
Authenticate user (Returns HTTP-Only Auth Cookie). |
All protected routes expect a valid Auth Cookie.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/urls |
Create: Shorten a new URL. Body: { "original_url": "..." } |
GET |
/api/urls/:id |
Retrieve: Get URL details (Original URL, Visit Count). |
PATCH |
/api/urls/:id |
Update: Update the target URL. |
DELETE |
/api/urls/:id |
Delete: Remove a short URL. |
cargo test.
├── sql/ # Database initialization scripts
├── src/
│ ├── config.rs # Environment configuration
│ ├── main.rs # Entry point & App Router
│ ├── ctx/ # Request Context (User Auth)
│ ├── model/ # Database Layer (Postgres + Redis)
│ │ ├── base.rs # Generic CRUD
│ │ ├── urls.rs # URL Logic
│ │ ├── user.rs # User/Auth Logic
│ │ └── visits.rs # Analytics Logic (Cron Job)
│ └── web/ # Web Layer (Axum Handlers)
│ ├── mw_auth.rs # Auth Middleware
│ └── ...
This project is licensed under the MIT License.