How to have the fastest possible incremental compilation using axum?

⚓ Rust    📅 2025-08-26    👤 surdeus    👁️ 3      

surdeus

I'm using Rust, axum and utoipa with utoipa-axum for the first time.

I'm creating one crate for operation (query or command) because I need development compilations (edit -> build -> run cycle) to be the fastest possible so right now I have these directories:

  • /Cargo.toml (workspace one)

  • /src/app/src/main.rs (the main executable)

  • /src/ops/player/Cargo.toml

  • /src/ops/player/src/types.rs (common types for all the sub-crates)

  • /src/ops/player/create/Cargo.toml

  • /src/ops/player/update/Cargo.toml

  • /src/ops/player/play/Cargo.toml

  • other hundreds ops here

  • /src/rest/Cargo.toml

  • /src/rest/src/router.rs which contains:

use utoipa_axum::{router::OpenApiRouter, routes};

pub fn new() -> OpenApiRouter<Arc<State>> {
    OpenApiRouter::new()
        .nest(
            "/player",
            OpenApiRouter::<Arc<State>>::new()
                .routes(routes!(player_create::handler))
                .routes(routes!(player_update::handler))
                .routes(routes!(player_play::handler))
        )
        .nest(
            "/team",
            OpenApiRouter::<Arc<State>>::new()
                .routes(routes!(team_include_player::handler))
                .routes(routes!(team_exclude_player::handler))
                .routes(routes!(team_do_something::handler))
        )
        // and so on other hundreds routes
}

Right now if I edit one query or command, for example player_update, /src/rest/ is invalidated since it depends on /ops/player.

Is there a way to avoid invalidation and only rebuild the single crate I changed?

Is there a way to "dinamically register routes", maybe at runtime? Why not? Or only during development?

6 posts - 5 participants

Read full topic

🏷️ Rust_feed