0Pricing
Learn Rust Coding · Lesson

Extractors

Parse requests.

Extractors is a free Learn Rust Coding lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What is an extractor?

An extractor is a handler parameter that pulls a piece of the request out for you. Axum inspects the parameter types and fills them in.

  • No manual request parsing
  • Type-driven and composable

Path extractor

Path captures dynamic URL segments. The type inside determines how the segment is parsed.

use axum::extract::Path;

async fn user(Path(id): Path<u32>) -> String {
    format!("user {}", id)
}

Multiple path params

Capture several segments by extracting a tuple. Order matches the path pattern.

use axum::extract::Path;

async fn item(Path((cat, id)): Path<(String, u32)>) -> String {
    format!("{} / {}", cat, id)
}

Query extractor

Query deserializes the URL query string into a struct using serde. Great for filters and pagination.

use axum::extract::Query;
use serde::Deserialize;

#[derive(Deserialize)]
struct Page { page: u32 }

async fn list(Query(p): Query<Page>) -> String {
    format!("page {}", p.page)
}

JSON body extractor

Json deserializes a request body into a struct. The struct must derive Deserialize.

use axum::Json;
use serde::Deserialize;

#[derive(Deserialize)]
struct NewUser { name: String }

async fn create(Json(u): Json<NewUser>) -> String {
    format!("created {}", u.name)
}

Headers extractor

Access headers with the HeaderMap extractor or typed header extractors. Useful for auth tokens.

use axum::http::HeaderMap;

async fn show(headers: HeaderMap) -> String {
    match headers.get("x-api-key") {
        Some(v) => format!("key: {:?}", v),
        None => "no key".to_string(),
    }
}

Extractor order matters

Body-consuming extractors like Json must come last in the parameter list, because the body can only be read once.

use axum::{Json, extract::Path};
use serde::Deserialize;

#[derive(Deserialize)]
struct Body { value: i32 }

async fn h(Path(id): Path<u32>, Json(b): Json<Body>) -> String {
    format!("{} {}", id, b.value)
}

Modeling extraction in plain Rust

Extraction is just parsing typed data out of a request. Here we deserialize a query-like string into numbers.

fn parse_query(q: &str) -> Option<u32> {
    q.strip_prefix("page=")?.parse().ok()
}

fn main() {
    println!("{:?}", parse_query("page=3"));
    println!("{:?}", parse_query("bad"));
}

Optional extraction

Wrap an extractor in Option to make it non-fatal. A missing or invalid value yields None instead of an error response.

use axum::extract::Query;
use serde::Deserialize;

#[derive(Deserialize)]
struct Filter { q: String }

async fn search(filter: Option<Query<Filter>>) -> String {
    match filter {
        Some(Query(f)) => f.q,
        None => "no filter".to_string(),
    }
}

Rejections

When an extractor fails it returns a rejection that becomes an HTTP error response. For example, invalid JSON yields a 422 automatically.

use axum::extract::rejection::JsonRejection;
use axum::Json;

async fn create(body: Result<Json<i32>, JsonRejection>) -> String {
    match body {
        Ok(Json(n)) => format!("ok {}", n),
        Err(_) => "bad body".to_string(),
    }
}

Combining extractors

A handler can use many extractors at once. Axum fills each from its part of the request.

use axum::{Json, extract::{Path, Query}};
use serde::Deserialize;

#[derive(Deserialize)]
struct Q { sort: String }
#[derive(Deserialize)]
struct B { name: String }

async fn h(Path(id): Path<u32>, Query(q): Query<Q>, Json(b): Json<B>) -> String {
    format!("{} {} {}", id, q.sort, b.name)
}

Quick Check

Test your understanding of extractors.

Recap

You learned to parse requests with extractors:

  • Path for URL segments, Query for the query string
  • Json for the body (must be last)
  • HeaderMap for headers
  • Option and Result handle failures gracefully

Next: shared state and JSON responses.

Frequently asked questions

Is the “Extractors” lesson free?

Yes — the full text of “Extractors” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Extractors”?

Parse requests. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Extractors” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Axum Routing
  2. Extractors
  3. JSON and State
  4. Middleware
← Back to Learn Rust Coding