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 Rust-native code generation
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.
cargo install --locked openapi-to-rustOpen source · MIT licensed · Rust 1.88+
openapi: 3.1.0
paths:
/v1/responses:
post:
operationId: createResponseOne contract. Both sides.
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.
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 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
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.
caller:
oneOf:
- $ref: '#/$defs/DirectCaller'
- $ref: '#/$defs/ServerCaller'
discriminator:
propertyName: type#[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
oneOf, anyOf, allOf, tagged and untagged enums.
Dates, UUIDs, URLs, bytes, unsigned integers, and per-format opt-outs.
Match documented API errors separately from transport failures.
Typed additionalProperties and extensible enum fallbacks.
Evidence over promises
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.
From spec to compiling code
Install the locked crate with Rust 1.88 or newer.
Use a local file or a safely fetched HTTPS document.
Check generated output into your project and detect drift in CI.
cargo install --locked openapi-to-rust
openapi-to-rust generate openapi.yamlDesigned for committed codegen
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.
openapi-to-rust generate openapi.yaml --check --quiet
cargo checkQuestions, answered
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.
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.
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.
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.
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.
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.
cargo install --locked openapi-to-rust