Actix Web Starter Template
Production-ready Actix Web API template with RBAC auth, PostgreSQL via SeaORM, Kafka-powered email, and a full Docker dev setup.
Overview
A robust template for building secure, scalable REST APIs in Rust using Actix Web. Includes token-based auth with roles/permissions, email verification via OTP, background jobs, and observability. Docker Compose spins up PostgreSQL, Kafka, and Kafka UI for a smooth local dev flow.
For detailed documentation, visit the GitHub repository: https://github.com/dev-davexoyinbo/actix-web-starter-template
- Token auth (non‑JWT), Argon2 hashes, email OTP verification
- RBAC: roles, permissions, and route-level middleware
- PostgreSQL + SeaORM entities, migrations, and seeders
- Kafka + SMTP for async email delivery (Askama templates)
- Tracing logs and request correlation IDs
- Makefile-driven DX; .env-based configuration
Highlights
Authentication & Access Control
- Token auth (non-JWT)
- RBAC roles and permissions
- Email verification (OTP)
- Route middleware for roles/permissions/conditions
Database
- PostgreSQL + SeaORM
- Entities with relations
- Migrations + seeders
- Separate test DB config
API & Middleware
- RESTful endpoints with DTO validation
- Pagination and structured errors
- Rate limiting and CORS
- Health/readiness endpoints
Messaging & Email
- Kafka producers/consumers
- Async email via SMTP
- Askama HTML templates
- Topic-based prioritization
Observability
- tracing + tracing-actix-web
- Correlation IDs
- Debuggable error types
- Performance-ready hooks
Security
- Argon2 password hashing
- Request size limits
- CORS and rate limiting
- Secret-driven config
Background Jobs
- actix-jobs scheduler
- Token cleanup job
- Extensible job registry
- Cron-style schedules
Developer Experience
- Docker Compose (PostgreSQL, Kafka, Kafka UI)
- Makefile (watch, test, migrate)
- bacon for live reload
- .env configuration
Quick Start
- Rust 1.86+, Docker, Docker Compose
- Copy
.env.exampleto.envand set values - Start services:
make up-dev - Run migrations (with seeding):
make migrate - Start app:
make run→ http://localhost:9000
For full setup, API docs, seeded users, and access control examples, see the GitHub README.
Code Snippets
Route + Access Control (RBAC)
use actix_web::{web, HttpResponse};
use crate::middlewares::auth_middleware::{AccessControl, AccessControlCondition};
pub fn config(cfg: &mut web::ServiceConfig) {
cfg
// Simple role check
.route("/api/admin", web::get().to(|| async { HttpResponse::Ok().finish() }))
.wrap(AccessControl::Role("admin".to_string()).into_middleware())
// Role AND permission
.route("/api/editor-blog", web::post().to(|| async { HttpResponse::Ok().finish() }))
.wrap(
AccessControlCondition::all()
.add(AccessControl::Role("editor".to_string()))
.add(AccessControl::Permission("blog:write".to_string()))
.into_middleware(),
);
}
Email Verification Middleware
use actix_web::{web, middleware::from_fn};
pub fn routes(cfg: &mut web::ServiceConfig) {
cfg.route("/api/verified-only", web::get().to(|| async { "ok" }))
.wrap(from_fn(crate::middlewares::auth_middleware::require_email_verification));
}
SeaORM Entity (User)
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub name: String,
pub email: String,
pub password_hash: String,
pub email_verified_at: Option<DateTimeWithTimeZone>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
Send Verification Email (Kafka + SMTP)
use messaging::{AppMessageTopic, AppMessageWrapper, EmailMessage, VerifyEmailTemplate};
use crate::globals;
pub async fn send_verification_email(name: &str, email: &str, otp: &str) -> Result<(), anyhow::Error> {
let messaging = globals::messaging::get()?;
let app = common::app_config::get()?;
let msg = AppMessageWrapper {
key: None,
topic: AppMessageTopic::GeneralEmail,
message: EmailMessage {
from: format!("{} <{}>", app.app.name, app.messaging.default_email_from),
to: format!("{} <{}>", name, email),
reply_to: None,
subject: "Verify your email".into(),
template: VerifyEmailTemplate { name: name.into(), otp: otp.into() }.into(),
}.into(),
};
messaging.read().await.send_message(msg).await?;
Ok(())
}
Quick cURL Test
# Login (use seeded users; see README for emails/passwords)
curl -X POST http://localhost:9000/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"admin@email.com","password":"<ADMIN_PASSWORD>"}'
For full examples and more snippets, see the README: https://github.com/dev-davexoyinbo/actix-web-starter-template
Other Projects

Canvas Gravity Balls
Pet project simulating bouncing balls with gravity, collisions, and elasticity on HTML Canvas.

Country flags and currency package
Lightweight TypeScript library for country flags, capitals, dial codes, currencies, and simple location distance utilities.

Trypema Rate Limiter
High-performance Rust rate limiting primitives with local and Redis-backed providers, atomic Redis enforcement, and absolute/suppressed strategies.