A simple, layered Todo REST API written in Rust using Actix-web.
- CRUD operations for Todo items
- Layered architecture:
- domain: core models, errors, repository trait
- app: business logic in
TodoService - infra: in-memory repository implementation
- interfaces: HTTP handlers, configuration, and routing
- Environment-based configuration (PORT, LOG_LEVEL)
- Logging via
env_logger - Comprehensive unit tests and HTTP handler tests
- Rust toolchain (1.70+)
- Cargo
- (Optional)
dotenv-cli
-
Clone the repository
git clone https://github.com/your-username/todo-api.git cd todo-api -
Configure environment Copy
.env.exampleto.envand adjust if needed:PORT=8080 LOG_LEVEL=info
-
Build & run
cargo run
The server will start on
http://localhost:8080.
| Method | Path | Description | Body |
|---|---|---|---|
| GET | / |
Health check (returns "OK") |
— |
| GET | /todos |
List all todos | — |
| GET | /todos/{id} |
Get a single todo by ID | — |
| POST | /todos |
Create a new todo | { "title": "..." } |
| PUT | /todos/{id} |
Update an existing todo | { "title": ".", "completed": true } |
| DELETE | /todos/{id} |
Delete a todo | — |
├── src
│ ├── app # Business logic
│ ├── domain # Core models, errors, and repository trait
│ ├── infra # In-memory repository implementation
│ ├── interfaces # HTTP handlers, extractors, router, config
│ ├── main.rs # Server bootstrap
│ └── lib.rs # Library exports
├── Cargo.toml # Dependencies & metadata
└── README.md # This file
Run the full test suite:
cargo testThe api.sh script uses atac to exercise all endpoints and verify only status codes without printing response bodies.
atac will automatically capture the id field from the last created todo response, and substitute it into any subsequent requests that reference {{TODO_ID}}.
By default, logs are printed at the level specified by the LOG_LEVEL environment variable. For example:
LOG_LEVEL=debug cargo runDual-licensed under MIT OR Apache-2.0. See LICENSE for details.