A high-performance URL shortener service built with Rust and Actix Web, featuring Redis for caching and rate limiting.
- URL Shortening: Convert long URLs into short, manageable links
- Custom Short URLs: Support for custom short URL aliases
- Expiration Control: Set custom expiration times for shortened URLs
- Rate Limiting: IP-based rate limiting to prevent abuse
- Redis Caching: Fast URL resolution with Redis backend
- Base62 Encoding: Efficient short URL generation
- HTTP Redirects: Proper 301 redirects for URL resolution
- Analytics: Click counter tracking for shortened URLs
- Framework: Actix Web 4.11.0
- Database: Redis (with r2d2 connection pooling)
- Configuration: YAML-based configuration
- Serialization: Serde for JSON handling
- URL Validation: Built-in URL parsing and validation
- Random Generation: Rand crate for unique ID generation
- Rust 1.70+ (2024 edition)
- Redis server
- Docker (optional, for Redis)
git clone <repository-url>
cd rust-shorten-urlcargo buildOption A: Using Docker
docker compose up -dOption B: Using Homebrew (macOS)
brew install redis
brew services start redisOption C: Manual Installation
# Download and install Redis from https://redis.io/download
redis-serverEdit configuration/base.yaml:
application:
host: "127.0.0.1"
base_url: "http://127.0.0.1"
port: 8000
domain: "localhost:8000" # Your domain for short URLs
api_quota: 10 # Rate limit per IP
redis_uri: "redis://127.0.0.1:6379"cargo runThe server will start on http://localhost:8000
Endpoint: POST /shorten
Request Body:
{
"url": "https://example.com",
"custom_short_url": "my-custom-link", // Optional
"expire_at": 24 // Optional, hours (default: 24)
}Response:
{
"url": "https://example.com",
"custom_short_url": "localhost:8000/abc123",
"expiry": 24,
"x_rate_remaining": 9,
"x_rate_limit_reset": 30
}Example:
curl -X POST http://localhost:8000/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "expire_at": 48}'Endpoint: GET /resolve/{short_url}
Response: HTTP 301 redirect to the original URL
Example:
curl -v http://localhost:8000/resolve/abc123Endpoint: GET /hello
Response: Basic health check with Redis connectivity test
The application uses YAML configuration files located in the configuration/ directory.
| Field | Description | Default |
|---|---|---|
application.host |
Server host | 127.0.0.1 |
application.port |
Server port | 8000 |
application.domain |
Domain for short URLs | localhost:8000 |
application.api_quota |
Rate limit per IP | 10 |
redis_uri |
Redis connection string | redis://127.0.0.1:6379 |
rust-shorten-url/
βββ src/
β βββ main.rs # Application entry point
β βββ lib.rs # Library exports
β βββ configuration.rs # Configuration management
β βββ startup.rs # Server startup logic
β βββ helpers.rs # Utility functions (Base62, URL validation)
β βββ routes/
β βββ mod.rs # Route module exports
β βββ shorten/
β β βββ mod.rs # Shorten module
β β βββ post.rs # POST /shorten handler
β βββ resolve/
β βββ mod.rs # Resolve module
β βββ get.rs # GET /resolve/{url} handler
βββ configuration/
β βββ base.yaml # Application configuration
βββ docker-compose.yml # Redis Docker setup
βββ Cargo.toml # Dependencies and metadata
The application implements IP-based rate limiting:
- Each IP address gets a quota of requests (configurable)
- Quota resets every 30 minutes
- Rate limit headers are included in responses
- Exceeded limits return HTTP 503 Service Unavailable
- Random URLs: Uses Base62 encoding with random 64-bit integers
- Custom URLs: Users can specify custom short URL aliases
- Collision Detection: Checks for existing custom URLs before creation
- Alphabet:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
- Click Counter: Tracks total clicks across all shortened URLs
- Redis Storage: All analytics data stored in Redis
- Real-time: Counter updates happen on each URL resolution
-
Create a short URL:
curl -X POST http://localhost:8000/shorten \ -H "Content-Type: application/json" \ -d '{"url": "https://github.com", "expire_at": 24}'
-
Resolve the short URL:
curl -v http://localhost:8000/resolve/{short_url} -
Test error cases:
# Non-existent URL curl http://localhost:8000/resolve/nonexistent # Invalid URL curl -X POST http://localhost:8000/shorten \ -H "Content-Type: application/json" \ -d '{"url": "invalid-url"}'
- Environment Variables: Use environment variables for sensitive configuration
- Redis Persistence: Enable Redis persistence for data durability
- Load Balancing: Deploy behind a load balancer for high availability
- Monitoring: Add logging and monitoring for production use
- HTTPS: Use HTTPS in production for security
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y ca-certificates
COPY --from=builder /app/target/release/rust-shorten-url /usr/local/bin/
COPY --from=builder /app/configuration /app/configuration
EXPOSE 8000
CMD ["rust-shorten-url"]- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Actix Web
- Redis for caching and session storage
- Inspired by modern URL shortener services
For support, please open an issue in the GitHub repository or contact the maintainers.
Happy URL Shortening! π