openapi-trait
A Rust proc-macro attribute that reads an OpenAPI specification file at compile time and generates typed Rust traits from it, so you can implement your API server or define a transport-agnostic client contract with full type safety and no boilerplate.
use PetstoreApi as _;
;
;
// Wire up an axum router.
let app = MyServer.router.with_state;
;
What gets generated
For every OpenAPI spec the macro emits inside the target module:
| Generated item | Source |
|---|---|
Structs with serde derives |
components/schemas |
{OperationId}Request structs |
Path, query, header params + request body per operation |
Per-operation {OperationId}Response enums |
HTTP status codes per operation |
impl axum::response::IntoResponse |
For every response enum generated by openapi_trait::axum |
{ModName}Api<S = ()> trait |
One method per operationId for server implementations |
{ModName}Client trait |
One method per operationId for transport-agnostic client implementations |
router method on the trait |
Wires all operations to an axum::Router when using openapi_trait::axum |
Crates
| Crate | Purpose |
|---|---|
openapi-trait |
Main entry point — add this to your Cargo.toml |
openapi-trait-axum |
Axum proc-macro — not for direct use |
openapi-trait-client |
Client proc-macro and ReqwestClient derive — not for direct use |
openapi-trait-shared |
Framework-agnostic codegen helpers — not for direct use |
Usage
Add to Cargo.toml:
[]
= "0.1"
Then apply the macro to a mod block:
Or generate a transport-agnostic client trait:
The path is resolved relative to the crate root (CARGO_MANIFEST_DIR). The
file is tracked by Cargo — the crate recompiles automatically when the spec
changes.
The generated trait name comes from the module name, so mod petstore {}
produces petstore::PetstoreApi and petstore::PetstoreClient.
Reqwest client support
openapi-trait enables the reqwest-client feature by default. That adds:
#[derive(openapi_trait::ReqwestClient)]for carrier structs that hold areqwest::Client- A blanket implementation of the generated
{ModName}Clienttrait for any type implementingopenapi_trait::ReqwestClientCore - Re-exports of
reqwestandpercent_encodingfor generated client code
Disable default features if you only want the transport-agnostic trait:
[]
= { = "0.1", = false }
OpenAPI support
| Feature | Status |
|---|---|
components/schemas → structs |
✅ |
| Path parameters | ✅ |
| Query parameters (including string enums) | ✅ |
| Header parameters | ✅ |
| Request bodies (JSON) | ✅ |
| Response enums per operation | ✅ |
allOf / anyOf / oneOf |
Partial — falls back to serde_json::Value |
| Security schemes | Not planned for v0.1 |