Uma API RESTful para um sistema de TODOs, desenvolvida em Rust, que serve como um projeto de estudo e demonstração da aplicação de padrões de arquitetura de software avançados, como Domain-Driven Design (DDD), Clean Architecture e CQRS, em um ambiente de Monólito Modular.
Este projeto não é apenas uma API CRUD, mas uma exploração prática de como estruturar uma aplicação robusta, testável e escalável em Rust.
A aplicação é dividida em quatro camadas distintas, com uma regra de dependência estrita que aponta sempre para o centro. Isso garante que a lógica de negócio (Domínio) seja independente de detalhes de implementação (Frameworks, Banco de Dados).
API (Presentation) → Application → Domain ← Infrastructure
- Domain: O coração da aplicação. Contém os agregados, value objects e as regras de negócio mais puras. Não depende de nada.
- Application: Orquestra os casos de uso (use cases), mediando a comunicação entre a API e o Domínio. É aqui que o padrão CQRS é aplicado.
- Infrastructure: Contém as implementações concretas de interfaces definidas no domínio, como o repositório para o MongoDB. Lida com o "mundo exterior".
- API: A camada mais externa, responsável por lidar com HTTP (requests e responses) usando o framework Axum.
A lógica de negócio é modelada através de agregados (Todo), Value Objects (TodoId, TodoName) e repositórios (definidos como traits no domínio). Isso cria um modelo rico e expressivo que representa fielmente o problema de negócio.
O projeto utiliza os workspaces do Cargo para separar cada camada da arquitetura em sua própria crate (domain, application, infrastructure, api). Isso força a separação lógica das responsabilidades, mesmo que a aplicação seja compilada e implantada como um único binário (um monólito).
A camada de aplicação é dividida em:
- Commands: Operações que alteram o estado do sistema (ex:
CreateTodoCommand). Retornam apenas o ID ou nada. - Queries: Operações que apenas leem o estado do sistema (ex:
ListAllTodosQuery). Retornam DTOs (Data Transfer Objects) otimizados para leitura.
- Linguagem: Rust
- Framework Web: Axum
- Runtime Assíncrono: Tokio
- Banco de Dados: MongoDB
- Driver do MongoDB: mongodb-rs
- Serialização: Serde
- Tratamento de Erros: thiserror
- Variáveis de Ambiente: dotenvy
- Outras crates importantes:
uuid,async-trait,futures.
git clone https://github.com/luizpoderoso/rust-todos-api
cd rust-todos-apiO projeto inclui um arquivo docker-compose.yml para iniciar uma instância do MongoDB facilmente.
docker-compose up -dCrie um arquivo .env na raiz do projeto, copiando o exemplo .env.example.
cp .env.example .envO arquivo .env já virá com os valores padrão para se conectar ao container Docker.
Use o Cargo para executar o monólito. Por padrão a crate api é o ponto de entrada.
cargo runO servidor estará rodando em http://localhost:3000.
-
Health Check
GET /health- Retorna200 OKse a API estiver no ar.
-
Todos
POST /todos- Cria um novo "todo".- Corpo do Request:
{ "name": "Implementar o README", "description": "Descrever o projeto de forma clara e objetiva." } - Resposta de Sucesso (201 Created):
{ "id": "e6a5c1b2-a4f3-4d21-9e8c-3e6a4b1c2d3e" }
- Corpo do Request:
GET /todos- Lista todos os "todos".- Resposta de Sucesso (200 OK):
[ { "id": "e6a5c1b2-a4f3-4d21-9e8c-3e6a4b1c2d3e", "name": "Implementar o README", "completed": false } ]
- Resposta de Sucesso (200 OK):
O projeto é um monólito modular que utiliza Cargo Workspaces para separar as camadas da Arquitetura Limpa.
.
├── 📄 .env.example
├── 📄 Cargo.toml # Define o workspace
├── 📄 docker-compose.yml
├── 📦 api/ # Crate de entrada, camada de apresentação (Axum)
├── 📦 application/ # Crate de casos de uso (CQRS)
├── 📦 domain/ # Crate com a lógica de negócio pura (agregados, VOs)
└── 📦 infrastructure/ # Crate com implementações (MongoDB, etc.)
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.