Skip to content

hungdv98/clean_architecture_todolist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Clean Architecture Todo List API

A production-ready Todo List REST API built with Rust, demonstrating Clean Architecture principles. This project showcases best practices for structuring scalable, maintainable, and testable Rust applications.

Architecture Overview

This project strictly follows Clean Architecture (also known as Hexagonal/Onion Architecture), ensuring:

  • Independence from frameworks – Business logic doesn't depend on web frameworks
  • Testability – Core logic can be tested without UI, database, or external services
  • Independence from UI – The UI can change without affecting business rules
  • Independence from database – Business rules aren't bound to a specific database
  • Independence from external agencies – Business rules don't know anything about the outside world
┌─────────────────────────────────────────────────────────────────────────────┐
│                              Bootstrap Layer                                │
│                    (Composition Root & Entry Point)                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                              Interfaces Layer                               │
│               (HTTP Handlers, DTOs, Routes, Middleware)                     │
├──────────────────────────────┬──────────────────────────────────────────────┤
│     Infrastructure Layer     │            Application Layer                 │
│  (Repos, DB, External APIs)  │       (Use Cases, Ports/Interfaces)          │
├──────────────────────────────┴──────────────────────────────────────────────┤
│                               Domain Layer                                  │
│              (Entities, Value Objects, Domain Errors)                       │
└─────────────────────────────────────────────────────────────────────────────┘

Layer Responsibilities

Layer Crate Responsibility
Domain crates/domain Core business entities, value objects, IDs, and domain errors. Zero external dependencies (except utilities).
Application crates/application Use cases (business logic orchestration), ports (trait definitions for repositories/services). Depends only on Domain.
Infrastructure crates/infrastructure Concrete implementations of ports: PostgreSQL repositories, JWT service, Argon2 password hashing, etc.
Interfaces crates/interfaces HTTP layer: Actix-web handlers, DTOs, routes, middleware, OpenAPI documentation.
Bootstrap crates/bootstrap Application composition root. Wires all dependencies and starts the server.

Dependency Flow

Bootstrap → Interfaces → Application → Domain
              ↓                ↑
         Infrastructure ──────┘
  • Domain has no dependencies on other layers
  • Application depends only on Domain
  • Infrastructure implements Application's ports (interfaces)
  • Interfaces uses Application's use cases
  • Bootstrap composes everything together

Features

  • User Authentication

    • Registration with email/password
    • Login with JWT access & refresh tokens
    • Logout (session revocation)
    • Token refresh
    • Get current user profile
  • Todo Management

    • Create, list, update, delete todos
    • Toggle completion status
    • User-scoped todos (isolation)
  • Security

    • Argon2 password hashing
    • JWT-based authentication
    • SHA-256 refresh token hashing
    • Session management with revocation support
  • API Documentation

    • OpenAPI/Swagger UI at /swagger-ui/

Tech Stack

Category Technology
Language Rust 1.92+ (Edition 2024)
Web Framework Actix-web 4.x
Async Runtime Tokio
Database PostgreSQL with SQLx
Authentication JWT (jsonwebtoken)
Password Hashing Argon2
API Docs utoipa + Swagger UI
Error Handling thiserror

Getting Started

Prerequisites

  • Rust 1.92.0 or later
  • PostgreSQL 14+
  • SQLx CLI (for migrations)
# Install SQLx CLI
cargo install sqlx-cli --no-default-features --features postgres

Setup

  1. Clone the repository
git clone https://github.com/hungdv98/clean_architecture_todolist.git
cd clean_architecture_todolist
  1. Configure environment variables

Create a .env file in the project root:

# Server
BIND_ADDR=127.0.0.1:8080

# Database
DATABASE_URL=postgres://user:password@localhost:5432/todolist

# JWT Configuration
JWT_SECRET=your-super-secret-key-at-least-32-characters
JWT_ISSUER=todoapp

# Token TTL
ACCESS_TTL_MINUTES=15
REFRESH_TTL_DAYS=7
  1. Create database and run migrations
# Create database
sqlx database create

# Run migrations
sqlx migrate run
  1. Build and run
# Development
cargo run

# Production
cargo build --release
./target/release/todoapp

The server will start at http://127.0.0.1:8080.

API Endpoints

Authentication

Method Endpoint Description
POST /v1/auth/register Register a new user
POST /v1/auth/login Login and receive tokens
POST /v1/auth/logout Logout and revoke session
POST /v1/auth/refresh Refresh access token
GET /v1/auth/me Get current user info

Todos

Method Endpoint Description
POST /v1/todos Create a new todo
GET /v1/todos List all user's todos
PATCH /v1/todos/{id} Update a todo
PATCH /v1/todos/{id}/done Toggle completion status
DELETE /v1/todos/{id} Delete a todo

Documentation

  • Swagger UI: http://localhost:8080/swagger-ui/
  • OpenAPI JSON: http://localhost:8080/api-docs/openapi.json

Project Structure

clean_architecture_todolist/
├── Cargo.toml                    # Workspace configuration
├── .env                          # Environment variables (not in repo)
├── migrations/                   # SQLx database migrations
│   └── 20260118043913_init.sql
└── crates/
    ├── domain/                   # Domain Layer
    │   └── src/
    │       ├── entities/         # Todo, User
    │       ├── ids/              # TodoId, UserId (typed IDs)
    │       ├── value_objects/    # Email, PasswordHash, TodoTitle
    │       └── error.rs          # Domain errors
    │
    ├── application/              # Application Layer
    │   └── src/
    │       ├── ports/            # Repository & service traits
    │       ├── usecases/
    │       │   ├── auth/         # Register, Login, Logout, etc.
    │       │   └── todos/        # CRUD operations
    │       └── error.rs          # Application errors
    │
    ├── infrastructure/           # Infrastructure Layer
    │   └── src/
    │       ├── db/               # Database connection pool
    │       ├── repos/            # SQLx repository implementations
    │       ├── security/         # JWT, Argon2, SHA256 implementations
    │       └── clock/            # System clock implementation
    │
    ├── interfaces/               # Interfaces Layer
    │   └── src/http/
    │       ├── handlers/         # HTTP request handlers
    │       ├── dto/              # Request/Response DTOs
    │       ├── middleware/       # Auth middleware
    │       ├── routes.rs         # Route configuration
    │       ├── state.rs          # Application state
    │       └── openapi.rs        # Swagger documentation
    │
    └── bootstrap/                # Bootstrap Layer
        └── src/
            ├── main.rs           # Entry point
            ├── config.rs         # Configuration loading
            └── wiring.rs         # Dependency injection

Testing Strategy

The Clean Architecture enables comprehensive testing at each layer:

# Run all tests
cargo test

# Run tests for a specific crate
cargo test -p domain
cargo test -p application
Layer Test Type What to Test
Domain Unit Entity behavior, value object validation
Application Unit/Integration Use case logic with mocked ports
Infrastructure Integration Repository implementations against test DB
Interfaces Integration HTTP handlers, request/response serialization

Development

# Format code
cargo fmt

# Lint
cargo clippy

# Check without building
cargo check

# Build documentation
cargo doc --open

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages