A production-ready Rust authentication service with user management, blog functionality, and comprehensive API documentation. Built with modern async web frameworks and industry best practices.
- Overview
- Key Features
- Technology Stack
- Quick Start
- Project Structure
- Core Modules
- API Endpoints
- Database Models
- Configuration
- CLI Commands
- Development
- Deployment
- Contributing
- License
RustAuth is a fully-featured authentication and content management API demonstrating modern backend development practices in Rust. It provides enterprise-grade security, scalability, and developer experience.
- JWT-based authentication with secure password hashing (Argon2)
- User management with CRUD operations and profiles
- Blog platform with posts and comments
- Email support for notifications and verification
- Redis integration for caching and sessions
- Comprehensive API documentation via Swagger UI
- CLI tooling for database management and scaffolding
- Database migrations with automatic change detection
- RBAC (Role-Based Access Control) ready
- Admin panel with AdminX framework
- JWT token-based authentication with configurable expiration
- Argon2 password hashing (resistant to GPU attacks)
- Role-based access control (RBAC) ready
- Secure credential validation
- Email verification support
- User registration with email validation
- User profile updates (email, password, profile info)
- User listing with pagination support
- Soft delete support for user data
- Account deactivation
- Create, read, update, delete blog posts
- Comments system for community engagement
- Post filtering and pagination
- Author attribution and timestamps
- Draft/publish status management
- PostgreSQL for persistent data storage
- Redis for caching and session management
- Structured logging with tracing
- Environment-based configuration
- Database migrations via Diesel
- CORS support for cross-origin requests
- Interactive API documentation (Swagger UI)
- OpenAPI 3.0 specification auto-generation
- Custom error handling with semantic HTTP status codes
- Database shell (
psqlwrapper) - Migration scaffolding tools
- Health check endpoints
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Web Framework | Axum | 0.8.8 | Modular & composable HTTP framework |
| Async Runtime | Tokio | 1.51.0 | Async execution engine |
| ORM/Query Builder | SQLx | 0.8.6 | Compile-time checked SQL queries |
| Migrations | Diesel CLI | - | Database schema management |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| JWT Tokens | jsonwebtoken | 10.3.0 | Token generation & validation |
| Password Hashing | Argon2 | 0.5.3 | GPU-resistant hashing |
| Random Generation | Rand | 0.10.0 | Secure randomization |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| JSON | Serde + Serde JSON | 1.0.228 + 1.0.149 | Type-safe serialization |
| Configuration | Config | 0.15.22 | Environment config parsing |
| Environment | dotenv | 0.15.0 | .env file loading |
| Date/Time | Chrono | 0.4.44 | Timezone-aware timestamps |
| UUID | UUID | 1.23.0 | Unique identifiers |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Cache/Session | Redis | 1.2.0 | In-memory data store |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Lettre | 0.11.21 | Email delivery | |
| Cron Jobs | Tokio Cron Scheduler | 0.15.1 | Scheduled task execution |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Logging | Tracing + Tracing Subscriber | 0.1.44 + 0.3.23 | Structured logging |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| OpenAPI Spec | Utoipa | 5.4.0 | Auto-generated API docs |
| Swagger UI | Utoipa Swagger UI | 9.0.2 | Interactive API explorer |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| CORS | Tower HTTP | 0.6.8 | Cross-origin resource sharing |
| Tower | Tower | 0.5.3 | Middleware & service utilities |
| Cookies | Axum Extra | 0.12.5 | Extended Axum utilities |
| Cookie Handling | Cookie | - | HTTP cookie operations |
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Error Types | Thiserror | 2.0.18 | Structured error definitions |
| Validation | Validator | 0.20.0 | Field-level validation |
| Error Context | Anyhow | 1.0.102 | Error context and chains |
- Rust Edition: 2024
- Default Binary:
authentication
┌─────────────────────────────────────────────────────────────────┐
│ Client Applications │
│ (Web, Mobile, Desktop, CLI Tools) │
└────────────────────────┬────────────────────────────────────────┘
│ HTTP/HTTPS
│
┌────────────────────────▼────────────────────────────────────────┐
│ Axum Web Server │
│ ┌─────────────────────────────────────────────────────────────┤
│ │ Routing Layer (Handlers, Controllers) │
│ │ ├── Auth Handlers (register, login) │
│ │ ├── User Handlers (CRUD operations) │
│ │ ├── Blog Handlers (posts, comments) │
│ │ └── Health & Status Endpoints │
│ └─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┤
│ │ Middleware Stack │
│ │ ├── Auth Middleware (JWT validation) │
│ │ ├── Logging Middleware (request/response tracking) │
│ │ ├── CORS Middleware (cross-origin handling) │
│ │ └── Error Handling Middleware │
│ └─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┤
│ │ Application Layer │
│ │ ├── State Management (AppState) │
│ │ ├── Configuration (AppConfig) │
│ │ └── Error Handling (AppError enums) │
│ └─────────────────────────────────────────────────────────────┘
└────────────────┬──────────────┬───────────────┬─────────────────┘
│ │ │
│ │ │
┌────────▼──┐ ┌───────▼──┐ ┌────────▼──┐
│ PostgreSQL│ │ Redis │ │ Email │
│ (Primary │ │ (Sessions,│ │ Service │
│ Datastore) │ Cache) │ │ (SMTP) │
└───────────┘ └───────────┘ └───────────┘
┌────────────────────────────────────┐
│ REST API Endpoints │
│ (OpenAPI Swagger UI Docs) │
└────────────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ Request Handlers Layer │
│ (user, blogs, auth controllers) │
└────────────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ Business Logic Layer │
│ (Validation, Authorization) │
└────────────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ Models & Schemas │
│ (Data structures, validation) │
└────────────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ Data Access Layer (SQLx) │
│ (Database queries, migrations) │
└────────────────────────────────────┘
│
┌────────────────▼────────────────────┐
│ External Services │
│ (PostgreSQL, Redis, Email) │
└────────────────────────────────────┘
- OS: Linux, macOS, or Windows (WSL2 recommended)
- RAM: 2GB minimum (4GB+ recommended)
- Disk: 2GB for dependencies and build artifacts
| Software | Version | Purpose | Installation |
|---|---|---|---|
| Rust | 1.70.0+ | Language & toolchain | rustup.rs |
| PostgreSQL | 14+ | Primary database | postgresql.org |
| Diesel CLI | 2.0.0+ | Migration management | cargo install diesel_cli --no-default-features --features postgres |
| Redis | 6.0+ | Cache & sessions | redis.io (optional) |
| psql | 14+ | PostgreSQL client | Included with PostgreSQL |
- Docker: For containerized PostgreSQL/Redis
- Git: For version control
- cargo-watch: For auto-reload during development (
cargo install cargo-watch) - sqlx-cli: For advanced SQL debugging (
cargo install sqlx-cli)
If you're new to Rust or this project, follow this detailed step-by-step guide. Each step explains what you're doing and why.
Before starting, verify your operating system and determine which installation method to use:
Windows Users:
- Use Windows Subsystem for Linux 2 (WSL2) or install native tools
- We recommend WSL2 for better compatibility
macOS Users:
- Make sure you have Xcode Command Line Tools installed
xcode-select --install
Linux Users (Ubuntu/Debian):
- Ensure you have build essentials installed
sudo apt-get update sudo apt-get install build-essential
Rust is the core language needed to compile and run this project.
All Operating Systems:
# Download and run the Rust installer
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Follow the prompts (usually just press Enter to accept defaults)
# Load Rust environment variables
source $HOME/.cargo/envVerify Installation:
rustc --version # Should print: rustc X.Y.Z (...)
cargo --version # Should print: cargo X.Y.Z (...)If you see version numbers, you're good to go! If not, restart your terminal and try again.
PostgreSQL is where we store user accounts, blog posts, and other data.
macOS (using Homebrew):
# Install Homebrew if you don't have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install PostgreSQL
brew install postgresql@15
# Start PostgreSQL service
brew services start postgresql@15
# Verify installation
psql --version # Should print: psql (PostgreSQL) X.Y.ZLinux (Ubuntu/Debian):
# Update package list
sudo apt-get update
# Install PostgreSQL
sudo apt-get install postgresql postgresql-contrib
# Start PostgreSQL
sudo systemctl start postgresql
# Verify installation
psql --versionWindows (WSL2):
# Inside your WSL2 terminal
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
# Start PostgreSQL
sudo systemctl start postgresql
# Verify installation
psql --versionDocker Alternative (All Platforms): If you have Docker installed, you can run PostgreSQL in a container:
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:15-alpine
# Verify it's running
docker psDiesel CLI helps manage database schema changes safely.
# Install Diesel CLI for PostgreSQL
cargo install diesel_cli --no-default-features --features postgres
# This takes a few minutes - it's compiling from source
# Verify installation
diesel --version # Should print: diesel X.Y.ZRedis is used for caching and session management. It's optional but recommended for production-like testing.
macOS:
brew install redis
brew services start redis
# Verify installation
redis-cli ping # Should print: PONGLinux (Ubuntu/Debian):
sudo apt-get install redis-server
sudo systemctl start redis-server
# Verify installation
redis-cli pingWindows (WSL2):
sudo apt-get install redis-server
sudo systemctl start redis-server
redis-cli pingDocker Alternative:
docker run -d \
--name redis \
-p 6379:6379 \
redis:7-alpine
# Verify it's running
docker exec redis redis-cli ping # Should print: PONGGet the project code from version control:
# Clone the repository
git clone <repository-url>
cd authentication
# Verify you're in the right directory
pwd # Should print path ending with 'authentication'
ls # Should show: Cargo.toml, README.md, migrations/, src/The .env file stores sensitive configuration that varies between environments:
# Create the environment file
cat > .env << 'EOF'
# Database Configuration
DATABASE_URL=postgres://postgres:postgres@localhost:5432/authentication_dev
DATABASE_POOL_SIZE=5
# Server Configuration
SERVER_ADDR=127.0.0.1
SERVER_PORT=8000
# JWT Configuration (use a strong 32+ character random string)
JWT_SECRET=your_super_secret_key_here_change_in_production_min_32_chars
JWT_EXPIRATION_HOURS=24
# Redis Configuration (optional)
REDIS_URL=redis://127.0.0.1:6379/0
# Email Configuration (optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM_EMAIL=noreply@example.com
# Logging
RUST_LOG=info,authentication=debug
# Environment
APP_ENV=development
EOFImportant: The .env file contains sensitive information and should never be committed to version control. Check your .gitignore file to ensure it contains .env.
Create a fresh PostgreSQL database for development:
# Simple method using createdb
createdb authentication_dev
# Verify it was created
psql -l | grep authentication_devIf createdb is not found, use this alternative:
psql -U postgres -c "CREATE DATABASE authentication_dev;"Migrations set up the database schema (tables, columns, relationships):
# Apply all pending migrations
cargo run --bin migrate
# Verify migrations ran successfully
# You should see messages like: "Running migration 20260407101804"
# Check migration status
cargo run --bin showmigrationsCompile the project and download all required libraries:
# Build the project (this takes several minutes on first run)
cargo build
# If build succeeds, you'll see: "Finished debug [unoptimized + debuginfo]"
# If there are errors, see the Troubleshooting section belowStart the web server:
# Start the application
cargo run
# Watch for output like:
# INFO authentication: Server listening on 0.0.0.0:8000
# INFO authentication: Connected to PostgreSQLThe server is now running! Keep this terminal open.
In a new terminal window, test the application:
# Check if the server is responding
curl http://127.0.0.1:8000/health
# Expected output: JSON response with status
# Open API documentation in your browser
open http://127.0.0.1:8000/swagger-ui/
# or on Linux/WSL:
# xdg-open http://127.0.0.1:8000/swagger-ui/🎉 Congratulations! Your project is now set up and running!
For experienced developers who just want to get started quickly:
# 1. Ensure Rust, PostgreSQL, Diesel CLI are installed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
# 2. For macOS
brew install postgresql@15 redis
brew services start postgresql@15 redis
cargo install diesel_cli --no-default-features --features postgres
# 3. For Linux (Ubuntu/Debian)
sudo apt-get install postgresql postgresql-contrib redis-server
sudo systemctl start postgresql redis-server
cargo install diesel_cli --no-default-features --features postgres
# 4. Clone and setup
git clone <repository-url>
cd authentication
# 5. Create .env
cp .env.example .env # OR create manually with your DATABASE_URL and JWT_SECRET
# 6. Setup database
createdb authentication_dev
cargo run --bin migrate
# 7. Build and run
cargo build
cargo run
# 8. Open your browser
open http://127.0.0.1:8000/swagger-ui/- OS: Linux (Ubuntu 20.04+), macOS (10.15+), or Windows (WSL2)
- RAM: 2GB minimum for compilation (4GB+ recommended)
- Disk: 5GB available space for dependencies and build artifacts
- Internet: Required for downloading dependencies
| Software | Version | Purpose | Status |
|---|---|---|---|
| Rust | 1.70.0+ | Language & compiler | Required |
| PostgreSQL | 14+ | Primary database | Required |
| Diesel CLI | 2.0.0+ | Database migrations | Required |
| Git | 2.25+ | Version control | Required |
| Redis | 6.0+ | Cache & sessions | Optional* |
*Optional but recommended for production-like testing
- Docker: Run PostgreSQL and Redis in containers
- cargo-watch: Auto-rebuild on file changes (
cargo install cargo-watch) - sqlx-cli: Advanced database debugging
- HTTPie or Insomnia: API testing (alternative to curl)
This section covers post-installation configuration for the application.
The .env file contains configuration specific to your development environment. Create it in the project root:
cp .env.example .env # If an example file existsOr manually create .env with:
# Database Configuration
# Modify the password if you set a different PostgreSQL password during installation
DATABASE_URL=postgres://postgres:postgres@localhost:5432/authentication_dev
DATABASE_POOL_SIZE=5
# Server Configuration
# 127.0.0.1 = localhost (only accessible from your machine)
# 0.0.0.0 = all network interfaces (accessible from other machines)
SERVER_ADDR=127.0.0.1
SERVER_PORT=8000
# JWT Configuration
# Generate a strong random secret: `openssl rand -base64 32`
# Must be at least 32 characters for production
JWT_SECRET=your_super_secret_key_here_change_in_production_min_32_chars
JWT_EXPIRATION_HOURS=24
# Redis Configuration (optional, leave as-is if using default Redis setup)
REDIS_URL=redis://127.0.0.1:6379/0
# Email Configuration (optional, for sending verification emails)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-specific-password
SMTP_FROM_EMAIL=noreply@example.com
# Logging Level
# Options: trace, debug, info, warn, error
# Use 'debug' for development, 'info' for production
RUST_LOG=info,authentication=debug
# Environment Type
# Options: development, staging, production
APP_ENV=developmentSecurity Best Practices:
⚠️ Never commit.envto git (check.gitignoreincludes it)- Use strong, random
JWT_SECRET(minimum 32 characters) - Generate secure secret:
openssl rand -base64 32 - Rotate credentials regularly in production
- Use environment-specific files:
.env.production,.env.staging - Update SMTP credentials for email functionality
Create a PostgreSQL database for development:
Method 1 (Recommended):
createdb authentication_devMethod 2 (Using psql):
psql -U postgres -c "CREATE DATABASE authentication_dev;"Method 3 (Interactive):
psql -U postgres
# At the psql prompt type:
# postgres=# CREATE DATABASE authentication_dev;
# postgres=# \qVerify the database was created:
psql -l | grep authentication_devApply the database schema using migrations:
# Run all pending migrations
cargo run --bin migrate
# Expected output shows each migration being appliedCheck migration status:
cargo run --bin showmigrationsTest that everything is configured correctly:
# Validate Rust code compiles
cargo check
# Expected: "Finished `dev` profile" with no errorsGenerate Rust code documentation:
# Generate and open HTML documentation
cargo doc --open
# Creates documentation for all crates and dependenciescargo runServer will start at http://127.0.0.1:8000
Output:
2026-04-10T10:30:45.123456Z INFO authentication: Server listening on 0.0.0.0:8000
2026-04-10T10:30:45.234567Z INFO authentication: Connected to PostgreSQL
2026-04-10T10:30:45.345678Z INFO authentication: Redis cache enabled
Open in browser:
- Swagger UI: http://127.0.0.1:8000/swagger-ui/
- OpenAPI JSON: http://127.0.0.1:8000/openapi.json
curl -X POST http://127.0.0.1:8000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecurePass123!",
"first_name": "John",
"last_name": "Doe"
}'Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"created_at": "2026-04-10T10:30:45Z"
}curl -X POST http://127.0.0.1:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecurePass123!"
}'Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400
}curl -X POST http://127.0.0.1:8000/api/blogs/posts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"title": "My First Post",
"content": "This is the content of my first blog post.",
"tags": ["rust", "webdev"]
}'| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/api/auth/register |
User registration | No |
POST |
/api/auth/login |
User login (returns JWT token) | No |
POST |
/api/auth/refresh |
Refresh JWT token | Yes |
POST |
/api/auth/logout |
Invalidate token | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
GET |
/api/users |
List all users (paginated) | Yes |
GET |
/api/users/:id |
Get user by ID | Yes |
PUT |
/api/users/:id |
Update user profile | Yes (owner or admin) |
DELETE |
/api/users/:id |
Delete user account | Yes (owner or admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/api/blogs/posts |
Create blog post | Yes |
GET |
/api/blogs/posts |
List blog posts (paginated) | No |
GET |
/api/blogs/posts/:id |
Get specific post | No |
PUT |
/api/blogs/posts/:id |
Update post | Yes (author) |
DELETE |
/api/blogs/posts/:id |
Delete post | Yes (author) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/api/blogs/posts/:postId/comments |
Create comment | Yes |
GET |
/api/blogs/posts/:postId/comments |
List comments | No |
PUT |
/api/blogs/comments/:id |
Update comment | Yes (author) |
DELETE |
/api/blogs/comments/:id |
Delete comment | Yes (author) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
GET |
/health |
Service health status | No |
GET |
/ready |
Readiness probe | No |
All API responses follow a consistent JSON structure:
Success Response (2xx):
{
"data": { /* actual response payload */ },
"status": "success",
"timestamp": "2026-04-10T10:30:45Z"
}Error Response (4xx/5xx):
{
"error": "Error message here",
"status": "error",
"code": "ERROR_CODE",
"timestamp": "2026-04-10T10:30:45Z"
}Include JWT token in all protected requests:
Authorization: Bearer <your_jwt_token># Debug build (faster, includes debug symbols)
cargo build
# Release build (optimized for production)
cargo build --release
# Check compilation without building
cargo check
# Watch mode (auto-rebuild on file changes)
cargo watch -x build# Run the main application
cargo run
# Run with release optimizations
cargo run --release
# Run with arguments
cargo run -- --port 9000
# Run specific binary
cargo run --bin migrate
cargo run --bin shell
cargo run --bin dbshell# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run specific test
cargo test test_user_registration
# Check code formatting
cargo fmt --check
# Auto-format code
cargo fmt
# Lint with Clippy
cargo clippy
# Full lint report
cargo clippy -- -W clippy::all# Apply pending migrations
cargo run --bin migrate
# Show migration status
cargo run --bin showmigrations
# Create new migration
cargo run --bin makemigrations -- create_table_users
# Get interactive SQL shell
cargo run --bin shell
# Open native PostgreSQL shell
cargo run --bin dbshell
# Generate migrations from app model changes
cargo makemigrations# Generate new app module (scaffolding)
cargo run --bin startapp -- my_app
# This creates: src/apps/my_app/
# ├── mod.rs
# ├── models.rs
# ├── handlers.rs
# ├── schemas.rs# Add a dependency
cargo add serde_yaml
# Update all dependencies
cargo update
# Outdated check
cargo outdated
# Generate dependency tree
cargo tree
# Security audit
cargo audit# Generate and open API docs
cargo doc --open
# Generate without opening
cargo doc
# Document private items
cargo doc --document-private-itemsMigrations are located in migrations/ directory:
migrations/
├── 00000000000000_diesel_initial_setup/
├── 2026-04-07-081504-0000_init/
├── 20260407101804_initial/
├── 20260407111624_auto/
├── 20260408074619_auto/
└── 20260408074647_auto/
Each migration contains:
up.sql— Schema changes to applydown.sql— Rollback instructions
diesel migration generate add_user_roles
# Creates: migrations/TIMESTAMP_add_user_roles/{up.sql,down.sql}
# Edit the SQL files, then run:
cargo run --bin migratecargo run --bin showmigrationsOutput:
Migrations:
[X] 00000000000000_diesel_initial_setup
[X] 2026-04-07-081504-0000_init
[X] 20260407101804_initial
[X] 20260407111624_auto
[X] 20260408074619_auto
[X] 20260408074647_auto
To rollback the last migration:
diesel migration redo --database-url "$DATABASE_URL"Interactive SQL shell:
cargo run --bin shellOr use native psql:
cargo run --bin dbshell-
Start Development Environment:
# Terminal 1: Start PostgreSQL brew services start postgresql # Terminal 2: Start Redis redis-server # Terminal 3: Run application with auto-reload cargo watch -x "run"
-
Edit Files & Test:
- Make code changes
- Cargo will auto-rebuild
- Test via Swagger UI or curl
-
Database Changes:
# Create new migration diesel migration generate add_new_field # Edit migrations/TIMESTAMP_add_new_field/up.sql # Then apply cargo run --bin migrate
src/
├── main.rs # Application entry point, routing, OpenAPI setup
├── config.rs # Configuration loading & validation
├── db.rs # Database connection pool setup
├── error.rs # Error types & conversion
├── response.rs # Response structures & serialization
├── state.rs # Application state management
│
├── models/ # Shared domain models
│ └── mod.rs
│
├── middleware/ # HTTP middleware
│ ├── auth.rs # JWT token validation
│ ├── logging.rs # Request/response logging
│ └── mod.rs
│
├── user/ # User module (auth & profile)
│ ├── mod.rs # Module exports
│ ├── models.rs # User data structures
│ ├── schemas.rs # Request/response schemas
│ └── handlers.rs # Endpoint handlers
│
└── blogs/ # Blog module (posts & comments)
├── mod.rs
├── models.rs # BlogPost, Comment models
├── schemas.rs # API request/response schemas
└── handlers.rs # Blog handlers
- Files:
module_name.rs(snake_case) - Modules:
mod.rsfor public exports - Functions:
handle_user_registration(snake_case) - Types:
UserRegistrationRequest(PascalCase) - Constants:
DATABASE_TIMEOUT(UPPER_SNAKE_CASE) - Database tables:
users,blog_posts,comments(snake_case, plural)
# Unit tests (same file)
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_creation() {
// ...
}
}
# Integration tests (tests/ directory)
# tests/auth_integration.rs
# tests/blog_integration.rs
# Run all tests
cargo test
# Run with logging
RUST_LOG=debug cargo test -- --nocaptureThis section covers common issues and their solutions.
Problem: The project fails to compile.
Solutions:
-
Ensure Rust is up to date:
rustup update cargo clean cargo build
-
Check for conflicting dependencies:
cargo tree cargo update
-
For Windows users, ensure you have Visual Studio Build Tools installed
Problem: Missing C compiler for linking native code.
Solutions:
-
macOS: Install Xcode Command Line Tools
xcode-select --install
-
Linux (Ubuntu): Install build essentials
sudo apt-get install build-essential
-
Windows: Download Visual Studio Build Tools from official website
Problem: PostgreSQL database hasn't been created yet.
Solutions:
# Create the database
createdb authentication_dev
# Or explicitly
psql -U postgres -c "CREATE DATABASE authentication_dev;"
# Verify creation
psql -l | grep authentication_devProblem: PostgreSQL credentials in .env are incorrect.
Solutions:
-
Verify PostgreSQL is running:
# macOS brew services list | grep postgres # Linux sudo systemctl status postgresql
-
Check your
.envDATABASE_URL:# Format: postgres://username:password@host:port/database # Common defaults: postgres://postgres:postgres@localhost:5432/authentication_dev
-
Reset PostgreSQL password:
psql -U postgres postgres=# ALTER USER postgres WITH PASSWORD 'newpassword'; postgres=# \q
Problem: Database migrations didn't apply correctly.
Solutions:
# Check migration status
cargo run --bin showmigrations
# Reset migrations (WARNING: deletes all data)
psql -U postgres -d authentication_dev -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
# Re-run migrations
cargo run --bin migrateProblem: PostgreSQL is not running or network connection failed.
Solutions:
# Start PostgreSQL service
# macOS
brew services start postgresql@15
# Linux
sudo systemctl start postgresql
# Verify PostgreSQL is listening
psql -U postgres -c "SELECT 1"Problem: Another process is using the server port.
Solutions:
# Find process using port 8000
lsof -i :8000 # macOS/Linux
netstat -ano | grep 8000 # Windows
# Kill the process (replace PID with actual process ID)
kill -9 <PID> # macOS/Linux
taskkill /PID <PID> /F # Windows
# Or change SERVER_PORT in .env to a different port (e.g., 8001)Problem: Redis is not running (it's optional but recommended).
Solutions:
# Start Redis
# macOS
brew services start redis
# Linux
sudo systemctl start redis-server
# Verify Redis is running
redis-cli ping # Should print: PONG
# To disable Redis (optional):
# Comment out or remove REDIS_URL from .envProblem: .env file isn't being loaded.
Solutions:
-
Verify
.envexists in project root:ls -la .env
-
Check
.envfile format (no spaces around=):# Correct DATABASE_URL=postgres://localhost/db # Incorrect DATABASE_URL = postgres://localhost/db
-
Reload environment variables:
# Stop cargo run (Ctrl+C) source .env cargo run
Problem: First build or compilation is very slow.
Solutions:
# This is normal for Rust! First build can take 5-10 minutes
# Subsequent builds are faster
# For development, use debug builds (faster):
cargo build # This is already the default
# Only use release if you need optimization:
cargo build --release # Much slower to build, but runs fasterProblem: Requests are taking longer than expected.
Solutions:
-
Enable query logging to see slow queries:
RUST_LOG=debug cargo run
-
Check PostgreSQL is running efficiently:
psql -U postgres -d authentication_dev -c "SELECT count(*) FROM users;" -
Ensure Redis is running (improves caching):
redis-cli ping
Problem: Can't run tests successfully.
Solutions:
# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run specific test
cargo test test_name
# Run tests in single-threaded mode (if tests interfere)
cargo test -- --test-threads=1Problem: Authentication token is invalid or expired.
Solutions:
-
Get a new token by logging in:
curl -X POST http://127.0.0.1:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "email": "user@example.com", "password": "SecurePass123!" }'
-
Include the token in subsequent requests:
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \ http://127.0.0.1:8000/api/users
Problem: Frontend cannot make requests due to CORS restrictions.
Solutions:
-
Ensure CORS middleware is enabled in
src/main.rs -
Configure allowed origins in
.envor code:# Add your frontend URL to allowed CORS origins -
For development, temporarily allow all origins (not for production):
// In src/main.rs .layer(cors_layer.allow_origin("*".parse().unwrap()))
If you encounter an issue not listed here:
-
Check logs: Run with debug logging
RUST_LOG=debug cargo run
-
Search issues: Check GitHub issues for similar problems
-
Community: Ask the Rust community at r/rust or Rust Discord
The application uses a unified error handling system via AppError:
pub enum AppError {
NotFound(String), // 404
BadRequest(String), // 400
Unauthorized(String), // 401
Forbidden(String), // 403
Conflict(String), // 409
Internal(String), // 500
Database(sqlx::Error), // 500
}Errors are automatically converted to JSON responses:
{
"error": "User not found",
"status": "error",
"code": 404,
"timestamp": "2026-04-10T10:30:45Z"
}- 400 Bad Request: Invalid JSON, missing required fields, validation errors
- 401 Unauthorized: Missing or invalid JWT token
- 403 Forbidden: Insufficient permissions for the resource
- 404 Not Found: Resource doesn't exist
- 409 Conflict: Duplicate email, conflicting state
- 500 Internal Error: Unexpected server errors, database failures
authentication/
├── Cargo.toml # Project manifest, dependencies
├── Cargo.lock # Locked dependency versions
├── README.md # This file
│
├── .env # Local environment variables (gitignored)
├── .gitignore # Git ignore rules
│
├── migrations/ # Database schema migrations
│ ├── 00000000000000_diesel_initial_setup/
│ ├── 20260407101804_initial/
│ ├── 20260407111624_auto/
│ └── 20260408074647_auto/
│
├── src/ # Application source code
│ ├── main.rs # Startup, middleware, and router mounting
│ ├── config.rs # Configuration management
│ ├── db.rs # Database setup
│ ├── error.rs # Error types
│ ├── response.rs # Response handlers
│ ├── state.rs # Application state
│ ├── apps/ # Self-contained feature apps
│ │ ├── mod.rs # Central app registry and OpenAPI wiring
│ │ ├── user/
│ │ │ ├── handlers.rs
│ │ │ ├── models.rs
│ │ │ ├── schemas.rs
│ │ │ └── mod.rs
│ │ └── blogs/
│ │ ├── handlers.rs
│ │ ├── models.rs
│ │ ├── schemas.rs
│ │ └── mod.rs
│ └── bin/ # CLI binaries
│ ├── dbshell.rs # PostgreSQL shell wrapper
│ ├── migrate.rs # Run database migrations
│ ├── makemigrations.rs # Create new migrations
│ ├── showmigrations.rs # Show migration status
│ ├── shell.rs # Interactive SQL shell
│ └── startapp.rs # App scaffolding generator
│
├── setup.md # Setup instructions
├── installation.md # Installation guide
├── development.md # Development workflow
│
└── target/ # Build artifacts (auto-generated)
├── debug/ # Debug builds
└── release/ # Release builds
| File | Purpose |
|---|---|
Cargo.toml |
Project metadata, dependencies, build configuration |
src/main.rs |
Application startup, middleware, and top-level router mounting |
src/apps/mod.rs |
Central app registry, route aggregation, and OpenAPI wiring |
src/config.rs |
Environment variable loading, AppConfig struct |
src/db.rs |
SQLx connection pool initialization |
src/error.rs |
Unified error types and HTTP conversion |
src/state.rs |
Shared application state (db pool, cache, config) |
src/apps/user/handlers.rs |
Register, login, user management endpoints |
src/apps/blogs/handlers.rs |
Blog CRUD endpoints |
migrations/*.sql |
Database schema and structure |
.env |
Local environment configuration |
-
Code Style
- Follow Rust naming conventions (snake_case for variables/functions)
- Maximum line length: 100 characters
- Use
cargo fmtbefore committing - Run
cargo clippyand fix warnings
-
Commits
- Use descriptive commit messages
- Format:
feat:,fix:,docs:,refactor:,test: - Example:
feat: add user email verification endpoint
-
Testing
- Write tests for new functionality
- Ensure all tests pass:
cargo test - Test error cases and edge conditions
-
Documentation
- Add doc comments to public functions
- Update README for significant changes
- Keep error messages descriptive
- Create feature branch:
git checkout -b feature/amazing-feature - Make changes and add tests
- Run:
cargo fmt,cargo clippy,cargo test - Commit with descriptive messages
- Push to repository
- Create pull request with description
Include:
- Rust version (
rustc --version) - PostgreSQL version
- Error message and backtrace
- Steps to reproduce
- Expected vs actual behavior
-
Database
- Use connection pooling (configured in
db.rs) - Enable query caching with Redis
- Add database indexes on frequently queried columns
- Use connection pooling (configured in
-
API
- Implement pagination for list endpoints
- Use gzip compression for responses
- Cache static content
-
Async Runtime
- Leverage Tokio's async capabilities
- Avoid blocking operations in handlers
- Use
tokio::spawnfor background tasks
-
Build
- Use
cargo build --releasefor production - Link-time optimization reduces binary size
- Strip debug symbols for deployment
- Use
Enable structured logging:
RUST_LOG=info,authentication=debug cargo runMonitor with ELK stack or similar for production deployment.
- Set strong
JWT_SECRET(min 32 characters) - Use HTTPS/TLS certificates
- Enable CORS with specific origins
- Configure production database backups
- Set up monitoring and alerting
- Enable structured logging
- Review security headers
- Test database migrations
- Document deployment process
- Set up rollback procedures
FROM rust:latest as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/authentication /usr/local/bin/
EXPOSE 8000
CMD ["authentication"]Build and run:
docker build -t rustauth:latest .
docker run -p 8000:8000 -e DATABASE_URL=... rustauth:latestIssue: DATABASE_URL not found
Error: `DATABASE_URL` environment variable not set
Solution: Create .env file with DATABASE_URL set.
Issue: Connection refused to PostgreSQL
Error: failed to connect to postgres://localhost:5432
Solution: Ensure PostgreSQL is running:
brew services start postgresql # macOS
sudo systemctl start postgresql # LinuxIssue: Migration fails
Error: Migration failed: column "field" does not exist
Solution: Check migration order and ensure all .up.sql files are valid SQL.
Issue: JWT token invalid
{"error": "Invalid token"}Solution: Ensure JWT_SECRET in .env matches the secret used to create the token.
Issue: Port already in use
Error: Address already in use (os error 48)
Solution: Change SERVER_PORT in .env or kill process on port 8000:
lsof -ti:8000 | xargs kill -9- setup.md — Detailed environment setup and configuration
- installation.md — Installation prerequisites and requirements
- development.md — Development workflow and best practices
We're here to help! When you encounter an issue:
- Check this README - Most common questions are answered here
- Review the Troubleshooting section - See Troubleshooting above
- Search GitHub Issues - Your question may already be answered
- Ask the Community - Post in forums or Discord servers
Official Documentation:
- Rust Book - Learn Rust fundamentals
- Rust Standard Library
- Rust by Example
Framework Documentation:
- Axum Web Framework - HTTP request handling
- Tokio Async Runtime - Async/await and multitasking
- SQLx Database Toolkit - Type-safe SQL queries
- PostgreSQL Documentation - Database reference
- Redis Documentation - Caching and sessions
Community:
- r/rust subreddit - Rust programming community
- Rust Discord Server - Real-time chat and support
- Rust Users Forum - Structured discussions
- Stack Overflow - rust tag - Q&A platform
Found a bug? Have a feature request?
-
Check existing issues - Avoid duplicates
-
Provide details:
- Error message and stack trace
- Steps to reproduce
- Your environment (OS, Rust version)
.envconfiguration (without secrets)
-
Create an issue on GitHub with the information above
Q: Can I use this in production?
A: Yes! This project is designed as a production-ready scaffold with security best practices. Before going live:
- Change
JWT_SECRETto a strong random value - Update SMTP credentials for emails
- Configure CORS origins properly
- Enable HTTPS/TLS
- Set up monitoring and logging
- Run
cargo auditto check for vulnerabilities - Review security policies and access controls
Q: How long does the first build take?
A: The first build typically takes 5-15 minutes depending on your machine. This is normal for Rust projects! Subsequent builds are much faster (usually under 1 minute).
To speed it up:
- Use a machine with multiple CPU cores
- Increase RAM available to your system
- Ensure you're using SSD storage (not spinning disk)
Q: Is Redis required?
A: No, Redis is optional for development.
- For development: Set
REDIS_URLor leave it blank to disable caching - For production: Recommended for caching and session management
To disable Redis:
- Comment out Redis imports in
src/main.rs - Remove or comment out
REDIS_URLfrom.env - Remove redis-related dependencies from
Cargo.toml
Q: How do I add a new module/app?
A: Use the scaffolding tool:
cargo run --bin startapp -- my_new_app
# This creates:
# src/apps/my_new_app/
# ├── mod.rs
# ├── models.rs
# ├── schemas.rs
# └── handlers.rsThen register it in src/apps/mod.rs.
Q: How do I modify the database schema?
A: Use Diesel migrations:
# 1. Create a new migration
cargo run --bin makemigrations -- migration_name
# 2. Edit the generated migration files
nano migrations/TIMESTAMP_migration_name/up.sql
nano migrations/TIMESTAMP_migration_name/down.sql
# 3. Apply the migration
cargo run --bin migrate
# 4. If needed, rollback
diesel migration redo --database-url "$DATABASE_URL"Q: How do I implement role-based access control (RBAC)?
A: Here's a basic implementation:
-
Add role column to users table:
ALTER TABLE users ADD COLUMN role VARCHAR(50) DEFAULT 'user';
-
Create a role enum in models:
#[derive(Debug, Clone, Copy, PartialEq)] pub enum UserRole { Admin, Moderator, User, }
-
Create authorization middleware:
pub fn require_admin(user_role: UserRole) -> Result<(), AppError> { if user_role != UserRole::Admin { return Err(AppError::Forbidden("Admin access required".to_string())); } Ok(()) }
-
Use in handlers:
pub async fn admin_endpoint(Extension(user): Extension<User>) -> Result<()> { require_admin(user.role)?; // ... handler logic Ok(()) }
Q: How do I test my API endpoints?
A: Several options:
Using curl (command line):
curl -X POST http://127.0.0.1:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"pass123"}'Using Swagger UI:
- Open
http://127.0.0.1:8000/swagger-ui/in your browser - Interactive testing with built-in documentation
Using Insomnia (GUI tool):
- Download from insomnia.rest
- Import OpenAPI spec from
http://127.0.0.1:8000/openapi.json
Using automated tests:
cargo test
cargo test -- --nocapture # See output
RUST_LOG=debug cargo test # With loggingQ: How do I deploy this to production?
A: Basic deployment steps:
-
Build for release:
cargo build --release # Binary at: ./target/release/authentication -
Set up environment:
- Install dependencies on server
- Create production
.envwith real credentials - Set up PostgreSQL database
-
Run migrations:
cargo run --bin migrate
-
Run the application:
./target/release/authentication
-
Set up reverse proxy (Nginx/Apache):
- Forward requests to
127.0.0.1:8000 - Enable TLS/HTTPS
- Set up rate limiting
- Forward requests to
Q: How do I handle secrets in production?
A: Best practices:
- Never commit
.envto git - Use environment variables on your server
- Use secrets management tools:
- AWS Secrets Manager
- HashiCorp Vault
- DigitalOcean App Platform
- Heroku Config Vars
Example with environment variables only:
export DATABASE_URL="postgres://..."
export JWT_SECRET="very_secure_key"
./target/release/authenticationQ: Can I dockerize this application?
A: Yes! Create a Dockerfile:
FROM rust:1.75 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libpq5 ca-certificates
COPY --from=builder /app/target/release/authentication /usr/local/bin/
EXPOSE 8000
CMD ["authentication"]Build and run:
docker build -t rustauth .
docker run -p 8000:8000 -e DATABASE_URL="..." rustauthQ: How do I improve API response times?
A: Optimization strategies:
-
Enable logging to find bottlenecks:
RUST_LOG=debug cargo run
-
Add database indexes:
CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_posts_user_id ON blog_posts(user_id);
-
Use Redis caching:
- Cache frequently accessed data
- Reduce database queries
-
Connection pooling:
- Adjust
DATABASE_POOL_SIZEin.env
- Adjust
-
Use release builds:
cargo build --release ./target/release/authentication
Q: How do I profile and optimize performance?
A: Tools and techniques:
# Build with profiling support
cargo flamegraph
# Or use perf on Linux
sudo perf record ./target/release/authentication
sudo perf report
# Check for slow SQL queries
RUST_LOG=sqlx=debug cargo runQ: I get "error: could not compile authentication"
A: Try:
- Update Rust:
rustup update - Clean build:
cargo clean && cargo build - Check Rust version:
rustc --version(should be 1.70.0+)
Q: My changes aren't showing up when I run the app
A: Solution:
- Stop the running server (Ctrl+C)
- Rebuild:
cargo build - Run again:
cargo run
For automatic rebuilds during development:
cargo install cargo-watch
cargo watch -x runQ: Permission denied when accessing PostgreSQL
A: PostgreSQL authentication issue. Try:
# Reset to default credentials
sudo -u postgres psql
# In psql prompt:
postgres=# ALTER USER postgres WITH PASSWORD 'postgres';
postgres=# \qQ: How do I contribute to this project?
A: Steps for contributors:
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feature/your-feature - Make changes and test thoroughly
- Run quality checks:
cargo fmt # Format code cargo clippy # Lint checks cargo test # Run tests cargo audit # Security audit
- Commit with descriptive message:
git commit -m 'feat: add new feature' - Push to your fork:
git push origin feature/your-feature - Create a Pull Request with description and screenshots
This project is licensed under the MIT License. See the LICENSE file for complete details.
- ✅ Allowed: Commercial use, modification, distribution, private use
- ❌ Prohibited: Trademark use, liability
⚠️ Required: License and copyright notice
Project Status: Active Development
Last Updated: April 21, 2026
Maintained By: Development Team
Rust Version: 1.70.0+
Current Build: stable
- Explore the Swagger UI for interactive API testing
- Read development.md for advanced development practices
- Check setup.md for detailed configuration options
- Review code examples in
src/apps/for reference implementations
Happy coding! 🚀