Skip to content

About

Use rust macros to derive a trait from OpenAPI that you can implement

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

openapi-trait

Build status Crates.io Documentation Guide

Turn an OpenAPI spec into Rust traits at compile time. Implement the trait to get a typed axum server, or use the generated trait as a transport-agnostic client with a ready-made reqwest implementation. You don't check in generated files or write a build.rs, and the code always matches the spec.

📖 Read the guide · 📚 API reference

[dependencies]
openapi-trait = "1"

Server

#[openapi_trait::axum("openapi/pets.yaml")]
pub mod pets {}

#[derive(Clone)]
struct PetServer;

impl pets::PetsApi for PetServer {
    type Error = pets::NotImplemented;

    async fn get_pet(
        &self,
        ctx: pets::get_pet::Context,
    ) -> Result<pets::get_pet::Response, Self::Error> {
        Ok(pets::get_pet::Response::Status200(pets::Pet {
            id: ctx.req.pet_id,
            name: "doggie".into(),
            status: None,
        }))
    }
    // Operations you don't implement yet answer `500 not implemented`.
}

use pets::PetsApi as _;
let app: axum::Router = PetServer.router();

Client

#[openapi_trait::client("openapi/pets.yaml")]
pub mod pets {}

#[derive(Clone, openapi_trait::ReqwestClient)]
struct PetsHttpClient {
    #[openapi_trait(client)]
    http: openapi_trait::reqwest::Client,
    #[openapi_trait(base_url)]
    base_url: String,
    #[openapi_trait(auth)]
    auth: pets::PetsAuthState,
}

use pets::{PetsClient as _, PetsClientAuth as _};

let client = PetsHttpClient {
    http: openapi_trait::reqwest::Client::new(),
    base_url: "http://localhost:3000".into(),
    auth: Default::default(),
}
.with_bearer_auth("secret");

let pet = client.get_pet(pets::get_pet::Request { pet_id: 1 }, None).await?;

pets::PetsClient is a plain trait, so you can also implement it yourself as a test double or on top of another transport.

Runnable versions of both examples are in openapi-trait/examples.

Features

  • Models. Structs and enums from components/schemas, including oneOf/anyOf/allOf, additionalProperties, and date-time/uuid formats.
  • Typed operations. A module per operation with a Request struct for path, query, header and body inputs, and a Response enum with one variant per status code.
  • Security. apiKey, HTTP bearer and HTTP basic. On the server, credentials are extracted and missing ones get a 401. On the client, they are injected into every call.
  • Streaming. Binary request and response bodies are streamed, never buffered.
  • Validation (opt-in). Schema constraints become serde_valid rules.
  • Go-to-definition. Add source_file (#[openapi_trait::axum("openapi/pets.yaml", source_file)]) and F12 in your IDE opens the generated code. It is written to a self-gitignored .openapi-trait/ folder (details).
  • Debug dump. Set OPENAPI_TRAIT_DEBUG=1 to write the generated code to disk.

See the OpenAPI support matrix for details.

License

MIT

About

Use rust macros to derive a trait from OpenAPI that you can implement

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages