Skip to content

A URL shortener service built with Rust, implementing CQRS (Command Query Responsibility Segregation) pattern and Clean Architecture principles.

License

Notifications You must be signed in to change notification settings

ahmlvs/rust-shortener-cqrs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔗 rust-shortener-cqrs

A URL shortener service built with Rust, implementing CQRS (Command Query Responsibility Segregation) pattern and Clean Architecture principles.

✨ Features

  • 🏗️ CQRS Architecture - Separate read and write operations
  • 🧹 Clean Architecture - Clear separation of concerns
  • Fast & Async - Built on Tokio and Axum
  • 🧪 Well-tested - Comprehensive test coverage
  • 🎯 Type-safe - Leveraging Rust's type system
  • 📦 In-memory storage - DashMap for concurrent access

🏛️ Architecture

CQRS Architecture

Architecture in Excalidraw

Project Structure

src/
├── app/              # Business logic
│   ├── command/      # Write operations (CQRS Command)
│   └── query/        # Read operations (CQRS Query)
├── adapters/         # Infrastructure adapters
│   └── inmemory/     # In-memory repository implementation
├── ports/            # External interfaces
│   └── httpapi/      # HTTP API (Axum)
├── di/               # Dependency Injection container
├── error.rs          # Error types
└── id_provider.rs    # ID generation (NanoID)

🚀 Quick Start

Prerequisites

  • Rust 1.70+ (2021 edition)

Run

cargo run

Server starts on http://localhost:3001

📚 API Documentation

Create Short URL

Request:

curl -X POST http://localhost:3001/ \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://google.com"}'

Response:

{
  "id": "abc123"
}

Get Full URL

Request:

curl http://localhost:3001/abc123

Response:

{
  "url": "https://google.com/"
}

Error Responses

Invalid URL:

# Request
curl -X POST http://localhost:3001/ \
  -H 'Content-Type: application/json' \
  -d '{"url": "not-a-valid-url"}'

# Response (400 Bad Request)
{
  "message": "Invalid URL"
}

URL Not Found:

# Request
curl http://localhost:3001/nonexistent

# Response (404 Not Found)
{
  "message": "Not found"
}

🧪 Testing

Run all tests:

cargo test

Run tests with output:

cargo test -- --nocapture

Run specific test:

cargo test test_invalid_url

🏗️ Development

Build

# Debug build
cargo build

# Release build (optimized)
cargo build --release

Run release build

./target/release/rust-shortener-cqrs

Code Quality

# Format code
cargo fmt

# Lint with Clippy
cargo clippy --all-targets --all-features -- -D warnings

⚙️ Configuration

Currently, the server port is hardcoded to 3001 in main.rs.

🛠️ Technology Stack

📝 TODO / Roadmap

  • Add persistent storage (PostgreSQL/Redis)
  • Environment-based configuration
  • Rate limiting middleware
  • URL scheme validation (http/https only)
  • SSRF protection
  • HTTP redirects instead of JSON response
  • Metrics and monitoring
  • Health check endpoint
  • Docker support
  • CI/CD pipeline

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

This project is open source and available under the MIT License.

🔍 Learn More

About

A URL shortener service built with Rust, implementing CQRS (Command Query Responsibility Segregation) pattern and Clean Architecture principles.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages