Skip to content
b
intermediateProgramming

Production Web Services in Rust

Build, test and ship an async HTTP service with Axum and MongoDB.

12 lessons2h 6m4 sections
brainggPractical engineering courses, written by people who ship
$49.99
  • Lifetime access to all lessons
  • 12 lessons across 4 sections
  • Progress tracking across devices

What you'll learn

  • Structure an Axum service that stays readable past ten thousand lines
  • Model documents in MongoDB without fighting the driver
  • Authenticate requests with JWTs and revoke them on demand
  • Test handlers without standing up the whole world

Course content

4 sections · 12 lessons · 2h 6m

FoundationsWhere the request goes and how the pieces fit together, before any database is involved.3 lessons
  • Why Axum, and what it is notFree preview9m
    Read this lesson
    Axum is a routing layer over `hyper` and `tower`. That sentence does more work than it looks like it does, and understanding it explains most of Axum's design. A `tower::Service` is a function from request to response, with backpressure. Axum's job is to pick which one of those runs for a given path, and to convert typed Rust values into and out of HTTP. It deliberately does not provide an ORM, a template engine, or a plugin system. Everything else you need is a `tower` layer that composes with the rest of the ecosystem. The practical consequence: when you want rate limiting, timeouts, compression or tracing, you are not looking for an Axum feature. You are looking for a `tower` layer, and it will work.
  • Handlers, extractors and the argument order ruleFree preview12m
    Read this lesson
    A handler is an async function whose arguments are extractors. Each one pulls something out of the request: ```rust async fn get_course( State(state): State<AppState>, Path(slug): Path<String>, Query(params): Query<CourseQuery>, Json(body): Json<UpdateCourse>, ) -> impl IntoResponse { /* … */ } ``` There is exactly one rule to remember: **the body-consuming extractor goes last**. `Json`, `Form` and `Bytes` consume the request body, so at most one can appear and it must be the final argument. Everything else reads only the head and can appear in any order. When you break the rule the error is a wall of trait-bound text about `FromRequestParts`. That is the compiler saying "this extractor needs the body, but the body was already taken".
  • Errors that are worth returning14m
Working with MongoDB3 lessons
  • Documents are not rows11m
  • Indexes you will actually need13m
  • Serializing timestamps without losing sortability10m
Authentication3 lessons
  • JWTs, and the revocation problem nobody mentions15m
  • Extractors as authorization12m
  • Hashing passwords, briefly8m
Testing and shipping3 lessons
  • Testing what is worth testing12m
  • Deploying a single binary10m
  • Where to go next

Requirements

  • Comfortable with Rust syntax, ownership and `Result`
  • Familiarity with HTTP verbs and status codes

Description

Most Rust web tutorials stop at a "hello world" handler. This one starts where those finish: how you lay a service out so it survives contact with a real product. We build a working API end to end — routing, extractors, database access, authentication, error handling and tests — and along the way explain why each piece is shaped the way it is. By the end you will have a service you could actually deploy, and the judgement to know which parts of it to change when your problem differs.

Student reviews