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.example
to.env
and 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 Infinity & Circle Mouse
Pet project exploring HTML Canvas and JavaScript animations—drawing an infinity curve and a circle following the mouse.

iPay (Nuxt 3 Pet Project)
A simple Nuxt 3 site built to explore the Nuxt 3 ecosystem, routing, layouts, and component patterns.

Auth module for Nuxt server apps
Auth module for Nuxt 3 server apps with local and social providers, tokens, middlewares, and typed composables.