Awesome-omni-skill rust-backend-advance

Production-ready Rust backend development with Axum framework and PostgreSQL. Master async patterns, tower middleware, SQLx database operations, authentication (JWT/OAuth), testing strategies, and deployment. Use when building REST APIs, microservices, or any Rust web backend with Axum.

install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/rust-backend-advance" ~/.claude/skills/diegosouzapw-awesome-omni-skill-rust-backend-advance && rm -rf "$T"
manifest: skills/development/rust-backend-advance/SKILL.md
source content

Rust + Axum Backend Mastery

Production-ready patterns for building scalable Rust backends with Axum and PostgreSQL.

When to Use This Skill

  • Building REST APIs or GraphQL with Axum
  • Designing database schemas with SQLx + PostgreSQL
  • Implementing authentication (JWT, OAuth 2.1)
  • Writing async code with Tokio
  • Creating middleware and extractors
  • Testing Axum applications
  • Deploying to production (Docker, Kubernetes)
  • Performance optimization and monitoring

Quick Start

Minimal Axum Server

use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(|| async { "Hello, Axum!" }));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Essential Dependencies (Cargo.toml)

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["cors", "trace"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres", "uuid", "time"] }
uuid = { version = "1", features = ["v4", "serde"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
thiserror = "1"
anyhow = "1"

Reference Navigation

Core Rust Patterns

TopicFileDescription
Rust Idiomsrust-patterns.mdEnums, iterators, error handling
Async/Tokioasync-tokio.mdAsync patterns, spawn, channels

Axum Framework (70%)

TopicFileDescription
Axum Guideaxum-complete-guide.mdRouting, handlers, state
Extractorsaxum-extractors.mdPath, Query, Json, State
Middlewaremiddleware-patterns.mdTower layers, auth middleware

Database (PostgreSQL)

TopicFileDescription
SQLxsqlx-postgresql.mdQueries, transactions, migrations
Patternsdatabase-patterns.mdConnection pools, optimization

Architecture

TopicFileDescription
Project Structureproject-structure.mdFolder organization
Patternsarchitecture-patterns.mdMicroservices, modulith

Security & Auth

TopicFileDescription
Authenticationauthentication.mdJWT, OAuth 2.1, sessions
Securitysecurity-owasp.mdOWASP Top 10 for Rust

Testing & Quality

TopicFileDescription
Testingtesting-guide.mdUnit, integration, E2E
Error Handlingerror-handling.mdHTTP errors, thiserror

DevOps & Production

TopicFileDescription
Deploymentdeployment.mdDocker, Kubernetes
Monitoringmonitoring.mdTracing, Prometheus

Decision Guide

When to Choose Axum (70% - Primary)

✅ Choose Axum when:
- Building new Rust web projects
- Need tower ecosystem compatibility
- Want ergonomic, type-safe extractors
- Prefer modular, composable design
- Need excellent async performance

When to Consider Alternatives (30%)

Actix-web - When you need:
- Maximum raw performance (benchmarks leader)
- Actor model for complex state
- Established ecosystem with more examples

Rocket - When you need:
- Simplest learning curve
- Most "magical" developer experience
- Rapid prototyping

Core Patterns Summary

Error Handling

use axum::{http::StatusCode, response::IntoResponse, Json};
use serde_json::json;

pub enum AppError {
    NotFound(String),
    Database(sqlx::Error),
    Unauthorized,
}

impl IntoResponse for AppError {
    fn into_response(self) -> axum::response::Response {
        let (status, message) = match self {
            Self::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
            Self::Database(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
            Self::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized".into()),
        };
        (status, Json(json!({ "error": message }))).into_response()
    }
}

Handler Pattern

use axum::{extract::{Path, State}, Json};
use uuid::Uuid;

async fn get_user(
    State(pool): State<PgPool>,
    Path(id): Path<Uuid>,
) -> Result<Json<User>, AppError> {
    let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
        .fetch_optional(&pool)
        .await?
        .ok_or_else(|| AppError::NotFound("User not found".into()))?;
    
    Ok(Json(user))
}

State Management

use std::sync::Arc;
use sqlx::PgPool;

#[derive(Clone)]
pub struct AppState {
    pub db: PgPool,
    pub config: Arc<Config>,
}

let app = Router::new()
    .route("/users/:id", get(get_user))
    .with_state(AppState { db: pool, config: Arc::new(config) });

Examples


Best Practices Checklist

API Design

  • Use proper HTTP methods (GET, POST, PUT, DELETE)
  • Return appropriate status codes
  • Validate input with extractors
  • Document with OpenAPI/Swagger

Database

  • Use connection pooling (SQLx built-in)
  • Always use parameterized queries
  • List columns explicitly (no SELECT *)
  • Use transactions for multi-step operations

Security

  • Validate all input
  • Use Argon2id for passwords
  • Implement rate limiting
  • Set security headers (tower-http)

Testing

  • Unit tests for business logic
  • Integration tests for handlers
  • Use testcontainers for database tests

Production

  • Structured logging (tracing)
  • Health check endpoints
  • Graceful shutdown
  • Docker multi-stage builds

Resources