← Índice

6.4 Lo que llega

Esta traducción fue asistida por IA y revisada superficialmente. Si encuentras errores o algo no suena natural, escríbeme — lo agradezco.

Una dirección lleva más que una indicación. “Tercer piso, apartamento doce” es una ruta y al mismo tiempo datos sobre a quién se busca. Un buen mensajero no pregunta en la puerta a quién viene a ver - lo leyó de camino. El handler recibía el hecho de la llegada. Lo que estaba escrito en el sobre - eso nunca lo miró.

Lo que necesitas

Dos handlers reciben un identificador de tarea en la ruta: GET /tasks/{id} y PATCH /tasks/{id}/done. Ahora mismo no pueden verlo - ambos responden igual para cualquier número.

Hace falta una forma de decirle al handler: esta petición lleva un {id}, y es tuyo.

La construcción

axum pasa los valores de la ruta al handler a través de los argumentos de la función: lee el tipo de cada argumento, toma lo necesario de la petición y lo entrega listo para usar.

Path<u64> es el tipo de argumento para un parámetro de ruta. axum sabe que la ruta contiene {id}, lo extrae y lo convierte a u64. Path(id): Path<u64> es destructuring: Path envuelve el valor, Path(id) lo desenvuelve y vincula el número al nombre id.

Actualiza crates/api/src/routes.rs:

// crates/api/src/routes.rs - CAMBIADO
use axum::{
    Router,
    extract::Path,
    routing::{get, patch, post},
};

async fn add() -> String {
    "TODO: add task".to_string()
}

async fn list() -> String {
    "TODO: list tasks".to_string()
}

async fn get_task(Path(id): Path<u64>) -> String {
    format!("task {id}")
}

async fn done(Path(id): Path<u64>) -> String {
    format!("marking {id} done")
}

pub fn router() -> Router {
    Router::new()
        .route("/tasks", post(add).get(list))
        .route("/tasks/{id}", get(get_task))
        .route("/tasks/{id}/done", patch(done))
}

add y list no reciben argumentos: sus rutas no contienen partes variables. crates/api/src/main.rs no cambia.

El resultado

$ make serve

En otro terminal:

$ curl localhost:3000/tasks/1
task 1

$ curl localhost:3000/tasks/42
task 42

$ curl -X PATCH localhost:3000/tasks/7/done
marking 7 done

Los handlers ven el número. Todavía no hay datos detrás. Pero la carta se lee ahora, no solo el sobre.

make ci pasa: los mismos 38 tests.

El código completo de tq para este capítulo está en 6-the-port/04-what-arrives/.


Lore: Cómo axum rellena los argumentos

Los argumentos que axum rellena a partir de la petición se llaman extractors. Path<T> es uno de ellos. El mecanismo es el mismo para todos: axum lee el tipo del argumento, busca una implementación del trait FromRequestParts o FromRequest, y la llama. Si la extracción falla - por ejemplo, si {id} no es un número - axum responde con un error por sí mismo, sin llamar al handler.