Saltar al contenido principal

Router

Router::new().route()

  • Permite definir las rutas y los métodos HTTP como get, post, put, etc.
pub async fn router() -> Router {
    Router::new()
        .route("/", get("Hello word"))
}

pub fn books_routes() -> Router<PgPool> {
    let routes = Router::new()
        .route("/", post(create))
        .route("/", get(get_all))
        .route("/{id}", get(get_by_uuid))
        .route("/{id}", patch(update))
        .route("/{id}", delete(delete_book));

    routes
}

Router::new().nest()

  • Anidar Router con prefijos, como /products, /users o /v1
  • Se pueden anidar varias veces (con diferentes Router::new())
  • Util para separar la aplicación en partes más pequeñas
use axum::{
routing::{get, post},
Router,
};

let user_routes = Router::new().route("/{id}", get(|| async {}));

let team_routes = Router::new().route("/", post(|| async {}));

let api_routes = Router::new()
.nest("/users", user_routes)
.nest("/teams", team_routes);

let app = Router::new().nest("/api", api_routes);

// Our app now accepts
// - GET /api/users/{id}
// - POST /api/teams

Router::new().merge()

  • Unir varios Router en uno solo
  • Útil para dividir la aplicación en partes más pequeñas
  • Útil para definir middleware en algunas rutas y no en todas las rutas
  • Subgrupos de rutas para aplicar el middleware
  • .merge() no permite definir prefijos como se haría con .nest()
use axum::{
routing::get,
Router,
};

// define some routes separately
let user_routes = Router::new()
.route("/users", get(users_list))
.route("/users/{id}", get(users_show));

let team_routes = Router::new()
.route("/teams", get(teams_list));

// combine them into one
let app = Router::new()
.merge(user_routes)
.merge(team_routes);

// could also do `user_routes.merge(team_routes)`

// Our app now accepts
// - GET /users
// - GET /users/{id}
// - GET /teams

Router::new().route().layer()

Se puede utilizar para agregar procesamiento adicional a una solicitud de un grupo de rutas.

Ell middleware solo se aplica a las rutas existentes. Por lo tanto, primero se deben agregar las rutas (o rutas de respaldo) y luego llamar layer. Las rutas adicionales que se agreguen después de la llamada a layer no tendrán el middleware.

Se puede aplicar los middlewares en diferentes niveles de las rutas ya que se apli:

  • Middleware en la raíz para aplicarlo a todas las rutas
  • Subgrupo de rutas para aplicar los middlewares, uniendo las rutas con merge
  • Para agregar middleware a un solo controlador, se puede utilizar MethodRouter::layer o Handler::layer.

Middleware en la raíz

  • A un grupo específico con nest()
  • A todas las rutas
pub async fn router() -> Router {
    let v1_routes = Router::new()
        .nest(
            "/books",
            // Aplicando junto con nest()
            books_routes().layer(middleware::from_fn(auth_middleware)),
        )
        .nest("/authors", author_routes());

    let routes = Router::new()
        .route("/", get(hello()))
        .nest("/auth", auth_routes())
        .nest("/v1", v1_routes)
        .with_state(db_pool().await);
        //.layer(); // Aplicando a TODAS las rutas, similar que `with_state()`
       
    routes
}

Middleware en subgrupos

pub fn author_routes() -> Router<PgPool> {
    let public_routes = Router::new()
        .route("/", get(get_all))
        .route("/{id}", get(get_by_id));

    let private_routes = Router::new()
        .route("/{id}", delete(delete_author))
        .layer(middleware::from_fn(auth_middleware)); // <== Middleware

    let merge_routes = Router::new().merge(public_routes).merge(private_routes);

    merge_routes
}

Middleware en cada ruta

  • Util para definir un middleware solo en alguna ruta