Extractors: Path & Query

1. Welcome and Icebreaker:

If you could create any API endpoint, what would it do?

2. Outline the Session:

Agenda:

  1. Concept Explanation: What are extractors? How do you use Path and Query in Axum?
  2. Live Coding: Capture path and query parameters in handlers.
  3. Tasks: Practice with your own endpoints and parameters.

Learning Outcomes:

  • Understand how to use extractors to get data from requests.
  • Use Path and Query to access URL parameters and query strings.

Expectations: Try to write your own extractors and ask questions if stuck!

3. Concept Explanation:

Extractors in Axum are types that “extract” data from incoming requests and pass them as arguments to your handler functions. Two common extractors are:

  • Path<T>: Extracts parameters from the URL path (e.g., /users/{id} in Axum 0.8).
  • Query<T>: Extracts and deserializes query string parameters (e.g., /search?q=term).

You can use structs with serde::Deserialize to automatically parse query parameters.

4. Live Coding Demonstration:

use axum::{extract::{Path, Query}, Router, routing::get};
use serde::Deserialize;

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

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

async fn search(Query(params): Query<Search>) -> String {
    format!("Search query: {}", params.q)
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/users/{id}", get(user))
        .route("/search", get(search));
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Best Practices:

  • Use serde::Deserialize for complex query parameters.
  • Validate extracted data as needed.

Common Pitfalls:

  • Forgetting to derive Deserialize for structs.
  • Mismatched parameter names in path/query and handler.

5. Tasks

  • Add a route /posts/{post_id} that extracts and displays the post ID.
  • Create a /filter endpoint that accepts multiple query parameters (e.g., ?tag=rust&sort=desc).
  • Try extracting both path and query parameters in a single handler.