dyson_http 0.1.1

Dyson HTTP API Support Crate
Documentation
# dyson_http

Dyson HTTP helpers for Axum services. This crate gives you:

- A ready-to-merge health check route: `/actuator/health`.
- A simple way to serve interactive API docs (Swagger UI, Redoc, RapiDoc, Scalar) backed by `utoipa`.
- Small macros to make wiring routes and documenting endpoints ergonomic.

Works great for small services or bootstrapping new ones quickly.

## Install

Add these to your `Cargo.toml`:

```toml
[dependencies]
axum = "0.8"
dyson_http = "0"
# You write the OpenAPI derives and use the axum routes macro in your app,
# so you also need these dependencies in your crate:
utoipa = { version = "5", features = ["axum_extras"] }
utoipa-axum = "0"
```

If you're working inside a workspace with this repo checked out, you can also use a path dependency while developing:

```toml
[dependencies]
dyson_http = { path = "../../crates/dyson_http" }
```

## Features

- Health check route
  - `dyson_http::http::health_check_routes()` merges a simple `GET /actuator/health` => `OK`.
- API documentation router
  - `dyson_http::http::docs::router_with_docs(OpenApiRouter)` exposes:
    - Swagger UI at `/swagger-ui`
    - Redoc at `/redoc`
    - RapiDoc at `/rapidoc`
    - Scalar (Minimal UI) at `/`
    - OpenAPI JSON is served from `/api/v1/openapi.json`.
- Doc helpers
  - Security scheme add-ons: `ApiKeySecuritySchemeAddon`, `JwtSecuritySchemeAddon` (implement `utoipa::Modify`).
  - Route helpers/macros: `register_routes!`, `route_docs!`, and `route_docs_with_name!` to help enrich operations.

## Quick start

### 1) Health check only

```rust
use axum::{Router, http::StatusCode};

#[tokio::main]
async fn main() {
    // Start with any router you have
    let app = Router::new()
        // Merge a simple health check endpoint: GET /actuator/health -> "OK"
        .merge(dyson_http::http::health_check_routes());

    let listener = tokio::net::TcpListener::bind(("0.0.0.0", 3000)).await.unwrap();
    axum::serve(listener, app).await.unwrap();
}
```

### 2) Add interactive API docs (Swagger UI, Redoc, RapiDoc, Scalar)

The example below shows a minimal API with a documented endpoint using `utoipa`. The `register_routes!` macro helps collect routes for your OpenAPI and the `router_with_docs` function exposes the documentation UIs.

```rust
use axum::{routing::get, Json, Router};
use serde::{Deserialize, Serialize};
use utoipa::{OpenApi, ToSchema};
use utoipa_axum::router::OpenApiRouter;

#[derive(Serialize, ToSchema)]
struct HelloResponse { message: String }

/// Simple hello endpoint
#[utoipa::path(
    get,
    path = "/hello",
    tag = "Hello",
    responses(
        (status = 200, description = "Hello message", body = HelloResponse)
    )
)]
async fn hello() -> Json<HelloResponse> {
    Json(HelloResponse { message: "Hello, world!".into() })
}

#[derive(OpenApi)]
#[openapi(
    // All your route functions go here
    paths(hello),
    // You can add schemas, tags, and modifiers as needed
)]
struct ApiDoc;

#[tokio::main]
async fn main() {
    // Collect your routes into an OpenApi-aware router
    let api_router: OpenApiRouter = dyson_http::register_routes!(hello);

    // Turn that into a service router with docs (Swagger UI, Redoc, RapiDoc, Scalar)
    let app: Router = dyson_http::http::docs::router_with_docs(api_router);

    // Add health check (optional)
    let app = app.merge(dyson_http::http::health_check_routes());

    let listener = tokio::net::TcpListener::bind(("0.0.0.0", 3000)).await.unwrap();
    axum::serve(listener, app).await.unwrap();
}
```

Docs will be available at:
- Swagger UI: http://localhost:3000/swagger-ui
- Redoc: http://localhost:3000/redoc
- RapiDoc: http://localhost:3000/rapidoc
- Scalar: http://localhost:3000/
- OpenAPI JSON: http://localhost:3000/http/v1/openapi.json

### 3) Optional: Add security schemes to your OpenAPI

If you need API key or JWT bearer auth schemes, you can apply our modifiers to your `OpenApi`:

```rust
use utoipa::Modify;

#[derive(utoipa::OpenApi)]
#[openapi(
    paths(hello),
    modifiers(&dyson_http::http::docs::ApiKeySecuritySchemeAddon, &dyson_http::http::docs::JwtSecuritySchemeAddon)
)]
struct ApiDoc;
```

## License

Licensed under either of
- Apache License, Version 2.0
- MIT license

at your option.