Rust-native code generation

An OpenAPI generator for Rust that survives real-world specs.

Generate strongly typed models, async Reqwest and SSE clients, and opt-in Axum server scaffolding from OpenAPI 3.0, 3.1, and experimental 3.2 documents.

Install with Cargoshell
cargo install --locked openapi-to-rust

Open source · MIT licensed · Rust 1.88+

INPUT // openapi.yaml
openapi: 3.1.0
paths:
  /v1/responses:
    post:
      operationId: createResponse
OUTPUT // src/generated
  • 01types.rsshared models
  • 02client.rsReqwest calls
  • 03server/Axum traits
CARGO CHECK
54supported real-world OpenAPI specs
3.0 + 3.1supported · 3.2 experimental
2 sidestyped clients + Axum servers
1 commandfrom document to Rust modules

One contract. Both sides.

Stop rebuilding the same API boundary twice.

Generate the client calls you consume and the server operations you host. Both sides use the same types.rs, so request and response models stay aligned with the contract.

01 / CLIENT

Call APIs with typed Reqwest methods.

Get async methods, auth, retries, tracing, typed response bodies, per-operation errors, and optional builders.

let response = client
    .create_response(request)
    .await?;
Explore Rust client generation
sharedtypes.rs
02 / SERVER

Implement a generated Axum trait.

Choose operations and get per-tag traits, typed response enums, routing, parameter extraction, and SSE-ready responses.

impl ResponsesApi for AppState {
    async fn create_response(…)
}
Explore Axum server generation

Messy specs → clean Rust

Model the wire shape you actually have.

Real API documents use nullable type arrays, nested composition, discriminator mappings, inline objects, and open-ended enums. The generator turns those shapes into readable Serde types.

OPENAPI // ONEOF
caller:
  oneOf:
    - $ref: '#/$defs/DirectCaller'
    - $ref: '#/$defs/ServerCaller'
  discriminator:
    propertyName: type
Generated types.rsrust
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum ToolResultCaller {
    #[serde(rename = "direct")]
    DirectCaller(DirectCaller),
    #[serde(rename = "server")]
    ServerCaller(ServerCaller),
}

Generated output shown above is taken from the project’s checked-in discriminator snapshot—not a hand-written ideal.Inspect the fixture

01

Composed schemas

oneOf, anyOf, allOf, tagged and untagged enums.

02

Typed formats

Dates, UUIDs, URLs, bytes, unsigned integers, and per-format opt-outs.

03

Typed failures

Match documented API errors separately from transport failures.

04

Open-ended data

Typed additionalProperties and extensible enum fallbacks.

Evidence over promises

Built against APIs people actually ship.

The repository contains 55 real-world documents. Fifty-four are supported OpenAPI specs; one Swagger 2.0 document is intentionally skipped. Every pull request generates all 54 and compile-checks the OpenAI and Anthropic outputs. Scheduled and manual CI compile-checks the full corpus.

OPENAIunions · SSE · typed errorsPR compile check
ANTHROPICcontent blocks · overlaysPR compile check
CLOUDFLARElarge schema surfacescheduled compile
+ 51 SPECSparse + generateevery pull request

From spec to compiling code

Try the Rust OpenAPI generator in 30 seconds.

STEP 01

Install the CLI

Install the locked crate with Rust 1.88 or newer.

STEP 02

Generate from YAML or JSON

Use a local file or a safely fetched HTTPS document.

STEP 03

Compile and commit

Check generated output into your project and detect drift in CI.

Terminalshell
cargo install --locked openapi-to-rust
openapi-to-rust generate openapi.yaml

Designed for committed codegen

Make drift a build failure.

Use --check in CI to fail when committed generated files no longer match the OpenAPI document or configuration. Use --dry-run first when you only want to inspect the plan.

CIshell
openapi-to-rust generate openapi.yaml --check --quiet
cargo check

Choosing a generator

Rust-focused or multi-language?

OpenAPI Generator is a mature multi-language project with separate rust client andrust-axum server targets. openapi-to-rust is intentionally narrower: a Cargo-native, Rust-focused workflow with shared types and selectable client and server operations.

Read the dated, source-linked comparison

Questions, answered

Rust OpenAPI generator FAQ

What is an OpenAPI generator for Rust?

An OpenAPI generator reads an API contract in YAML or JSON and emits Rust code from it. openapi-to-rust generates Serde models, an optional async Reqwest client, optional SSE support, and optional Axum server scaffolding.

Does openapi-to-rust support OpenAPI 3.1?

Yes. OpenAPI 3.0 and 3.1 documents are accepted. OpenAPI 3.2 parsing is experimental; some less-common keywords are retained or modeled without changing generated runtime behavior. The compatibility page documents the boundaries.

Can it generate an Axum server from OpenAPI?

Yes. Select individual operation IDs, routes, or tags. The generator emits per-tag traits, response enums, parameter extraction, routing, and SSE-ready response variants for the selected surface.

How is this different from OpenAPI Generator’s Rust target?

OpenAPI Generator serves many languages and exposes separate Rust client and Rust server generators. openapi-to-rust focuses only on Rust and can generate shared models plus selected Reqwest client and Axum server operations in the same project. The comparison page links to both projects’ current documentation.

Can I generate only the operations I use?

Yes. Client and server selectors accept an exact operationId, an exact METHOD /path, or tag:name. Optional model pruning retains schemas reachable from the union of selected client and server operations.

Does generated code validate every OpenAPI constraint at runtime?

No. Constraints such as minimums, maximums, and patterns are emitted as Rust documentation, not runtime validators. This keeps generated dependencies smaller and makes the behavior explicit.

Your API contract already knows the types.

Put them in your Rust project.

Installshell
cargo install --locked openapi-to-rust