Extensiones
Las extensiones, al igual que en Axum, permiten almacenar y compartir datos a lo largo del ciclo de vida de una request HTTP. En Sword son especialmente útiles para compartir información entre interceptors web y controladores.
Controladores web
Insertar datos desde un interceptor
Un interceptor web puede insertar valores dentro de req.extensions antes de delegar la ejecución al siguiente paso del pipeline.
use sword::prelude::*;
use sword::web::*;
use uuid::Uuid;
#[derive(Interceptor)]
struct RequestIdInterceptor;
impl OnRequest for RequestIdInterceptor {
async fn on_request(&self, mut req: Request) -> WebInterceptorResult {
let request_id = Uuid::new_v4();
req.extensions.insert::<Uuid>(request_id);
req.next().await
}
}Leer extensiones desde un controller
Luego, un controlador web puede leer ese valor desde la misma request:
use sword::prelude::*;
use sword::web::*;
use uuid::Uuid;
#[controller(kind = Controller::Web, path = "/api")]
#[interceptor(RequestIdInterceptor)]
struct ApiController;
impl ApiController {
#[get("/data")]
async fn get_data(&self, req: Request) -> JsonResponse {
let request_id = req.extensions.get::<Uuid>().cloned();
JsonResponse::Ok().data(serde_json::json!({
"request_id": request_id,
}))
}
}Este patrón es útil para compartir:
- request ids
- información de autenticación
- flags calculadas por interceptors o layers
- contexto de trazabilidad
Mutabilidad de la request
Si necesitas insertar o modificar extensiones dentro de un interceptor, debes recibir la request como mutable:
async fn on_request(&self, mut req: Request) -> WebInterceptorResultSi solo necesitas leer extensiones dentro del controlador, no hace falta que la request sea mutable.
Request y StreamRequest
Tanto Request como StreamRequest exponen extensiones. Eso permite reutilizar el mismo patrón también en rutas streaming.
Por ejemplo, un interceptor de StreamRequest puede insertar datos en req.extensions y el handler puede leerlos más adelante.
Controladores Socket.IO
En Socket.IO existe un concepto relacionado, pero distinto:
ctx.extensions()da acceso a las extensiones del socketctx.http_extensions()da acceso a las extensiones HTTP asociadas a la request inicial
Esto resulta útil cuando necesitas compartir información entre el handshake HTTP y la fase posterior de eventos en tiempo real.
Cuándo usar extensiones
Usa extensiones cuando necesites compartir estado derivado de una request o conexión sin convertirlo en una dependencia fija del controller.
En cambio, si el dato es estructural o permanente en la aplicación, normalmente será mejor modelarlo como una dependencia inyectada.

