A comprehensive, multi-chapter tutorial for building production-grade web applications with the Axum framework in Rust.
By the end of this tutorial, you will have built a production-ready REST API with:
- User authentication (JWT-based, with bcrypt password hashing)
- Database persistence (PostgreSQL with SQLx for compile-time checked queries)
- Comprehensive error handling (structured API errors with proper HTTP status codes)
- Request validation (input validation with descriptive error messages)
- Middleware stack (logging, request ID tracing, rate limiting, CORS)
- Observability (structured logging with
tracing, metrics withmetrics) - Health checks and readiness probes (liveness, readiness, deep health checks)
- Testing strategy (unit, integration, and property-based tests)
- Graceful shutdown and configuration management
This tutorial assumes no prior Rust knowledge. We introduce Rust concepts progressively, explaining not just how things work but why they are designed that way. If you already know Rust, you can skim the fundamentals chapter, but we recommend reading the design decision sections throughout.
If you are an experienced developer coming from another language (Node.js, Python, Go, Java), you'll find many concepts familiar but expressed with Rust's unique philosophy of zero-cost abstractions and compile-time safety.
| Chapter | Topic | New Rust Concepts | Production Skills |
|---|---|---|---|
| Chapter 0 | Introduction & Tooling Setup | cargo, rustup, crates |
Project structure |
| Chapter 1 | Rust Fundamentals | Ownership, borrowing, types, structs, enums, pattern matching, Result, Option, match, if let, Vec, HashMap, String vs &str, lifetimes |
Reading Rust code |
| Chapter 2 | Your First Axum Server | async/await, tokio, futures, traits, closures |
Running an HTTP server |
| Chapter 3 | Routing & Handlers | Method routing, path parameters, IntoResponse, tuples |
REST API design |
| Chapter 4 | State & Extractors | Shared state, Arc, Arc<Mutex<T>>, extractors, FromRequest, generics, trait bounds |
Dependency injection, DI containers |
| Chapter 5 | Error Handling & Responses | thiserror, anyhow, IntoResponse for errors, custom error types, ? operator |
Structured API errors |
| Chapter 6 | Middleware with Tower | Tower layers, Service, Layer, AddExtensionLayer, request extensions, Pin, BoxFuture |
Cross-cutting concerns |
| Chapter 7 | Database Integration | SQLx, compile-time query checking, migrations, connection pooling, sqlx::migrate! |
Data persistence |
| Chapter 8 | Authentication & Authorization | JWT, bcrypt, password hashing, tower-http auth, claims, FromRequestParts |
Security best practices |
| Chapter 9 | Testing Your Application | tokio::test, reqwest, test databases, sqlx::test, mocking, tower::ServiceExt::oneshot |
Test-driven development |
| Chapter 10 | Observability & Health Checks | tracing, tracing-subscriber, metrics, OpenTelemetry, health check patterns |
Production monitoring |
| Chapter 11 | Production Readiness | Configuration (figment/config), graceful shutdown, TLS, Docker, jemalloc, optimization |
Deployment |
| Chapter 12 | The Complete Application | — | Architecture review |
Every chapter includes Design Decision callouts where we explain why we chose a particular approach. For example:
- Why use
Arcfor shared state instead of global variables? - Why does Axum use
IntoResponserather than a single response type? - Why is
tracingpreferred overlog? - Why compile-time SQL checking matters for production apps?
Each chapter includes:
- Working code examples that compile and run
- Exercises to reinforce concepts
- Common pitfalls and how to avoid them
We start with a single-file "Hello, World!" server and end with a multi-module application with database migrations, authentication, middleware, and observability. Each chapter builds incrementally on the previous one.
You will need:
- A computer running Linux, macOS, or Windows with WSL2.
- ~5GB of disk space for Rust toolchain, dependencies, and examples.
- Internet access for downloading crates.
- Docker (optional, for PostgreSQL in Chapters 7+)
No prior Rust knowledge is required. No prior web framework experience is required.
If you get stuck:
- Compile the error — Rust's compiler is famously helpful. Read the entire error message.
- Check the chapter's "Common Errors" section at the end.
- Compare with the reference implementation in Chapter 12.
Ready to start? Head to Chapter 0: Introduction & Tooling Setup.
This tutorial is a living document. The Axum ecosystem evolves quickly, and we aim to keep the content current with the latest stable versions.