Skip to content

[bug]: Generated Axum routes use 0.8 path syntax while requiring Axum 0.7 #38

Description

@angelcervera

Version or commit

openapi-to-rust 0.8.0 / Commit: 8e95847

Affected area

Generated Axum server

Minimal OpenAPI fragment

openapi: 3.1.0
info:
  title: Axum path parameter reproduction
  version: 1.0.0

paths:
  /samples/{sampleId}:
    get:
      operationId: getSample
      tags:
        - samples
      parameters:
        - name: sampleId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Sample found

Configuration and command

openapi-to-rust.toml:

[generator]
spec_path = "openapi.yaml"
output_dir = "src/generated"
module_name = "reproduction"

[features]
enable_async_client = false

[server]
framework = "axum"
operations = ["getSample"]
prune_models = false


Generation command:
`openapi-to-rust generate --config openapi-to-rust.toml`

The generated dependencies were merged into the consuming crate as instructed by `src/generated/REQUIRED_DEPS.toml`.

Actual behavior

Generation and compilation succeed, but the generated route does not match normal parameter values at runtime.

The generated router contains:

.route(
    "/samples/{sampleId}",
    ::axum::routing::get(get_sample_handler::<T>),
)

The generated handler expects an extracted path parameter:

async fn get_sample_handler<T>(
    ::axum::extract::State(api): ::axum::extract::State<T>,
    ::axum::extract::Path(sample_id): ::axum::extract::Path<String>,
) -> ::axum::response::Response
where
    T: super::api::SamplesApi + Clone + Send + Sync + 'static,
{
    // ...
}

However, the generated dependency fragment requires Axum 0.7:
axum = { version = "0.7", default-features = false, features = ["json"] }

Axum 0.7 uses :sampleId for path captures. It treats {sampleId} as a literal segment.

Consequently:

curl -i \
  http://127.0.0.1:3000/samples/6df2650e-16a8-4a70-b746-6f46a62efade

returns:

HTTP/1.1 404 Not Found
content-length: 0

The source appears to contain the incorrect assumption directly:

/// OpenAPI uses `{param}` placeholders; axum 0.7 accepts the same
/// `{param}` syntax for typed extraction, so this is currently a
/// pass-through.
fn openapi_to_axum_path(p: &str) -> String {
    p.to_string()
}

There is no configuration option to select an Axum version. ServerSection only exposes framework, operations, and prune_models, and the generated dependency version is hardcoded to Axum 0.7.

Expected behavior

When generating for Axum 0.7, OpenAPI path parameters should be translated to Axum 0.7 syntax:

.route(
    "/samples/:sampleId",
    ::axum::routing::get(get_sample_handler::<T>),
)

Alternatively, the generator could consistently target Axum 0.8 by:

  • Generating {sampleId} routes.
  • Requiring Axum 0.8.
  • Updating other generated APIs that are not compatible with Axum 0.8, such as #[axum::async_trait].

The generated route syntax and generated dependency version should always target the same Axum API.

Environment

Ubuntu 26.04 LTS, x86_64, rustc 1.97.1, cargo install --locked openapi-to-rust --version 0.8.0

Checks

  • I removed credentials and private API data.
  • I searched existing issues for this behavior.
  • This is not a security vulnerability.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions