OpenAPI
Generate an OpenAPI 3.1 document from route metadata and publish it through an endpoint you explicitly define.
OpenAPI has three parts: controller/action metadata, builder configuration, and an endpoint that returns the document. JSON or Swagger UI routes are not added automatically.
Metadata and a JSON endpoint#
This example is a separate, small application module. It uses the HTTP and Serde dependencies from the first application:
use std::sync::Arc;
use lilyrs::http_api::{
controller, AppBuilder, Controller, ControllerInitError, ControllerTrait,
Extensions, HttpApiError, OpenApiConfig, OpenApiJson, OpenApiService, Service,
};
use lilyrs::http_api::utoipa::{self, ToSchema};
use serde::Serialize;
#[derive(Serialize, ToSchema)]
struct Status { ready: bool }
#[derive(Controller)]
#[base_path("/contract")]
#[openapi(tag = "Contract")]
struct ContractController;
#[lilyrs::http_api::async_trait::async_trait]
impl ControllerTrait for ContractController {
async fn new(_: Arc<Extensions>) -> Result<Self, ControllerInitError> { Ok(Self) }
}
#[controller]
impl ContractController {
#[get("/status")]
#[openapi(operation_id = "contract.status", summary = "Örnek yanıt")]
async fn status(&self) -> Result<Status, HttpApiError> { Ok(Status { ready: true }) }
#[get("/openapi.json")]
#[openapi(skip)]
async fn document(&self, Service(openapi): Service<OpenApiService>)
-> Result<OpenApiJson, HttpApiError>
{
Ok(openapi.json()?)
}
}
async fn run() -> Result<(), Box<dyn std::error::Error>> {
let config = OpenApiConfig::new("Örnek API", "1.0.0")?;
AppBuilder::new("127.0.0.1:8080").tls_disabled()
.openapi(config).build().await?.start().await?;
Ok(())
}Run the example's async run() function from the first application's runtime entry point. GET /contract/openapi.json returns the document, and GET /contract/status returns the sample response. The status action's ready: true is only a DTO example; use HttpHealthService for actual readiness.
Schema import#
The self in use lilyrs::http_api::utoipa::{self, ToSchema} matters. This import resolves the utoipa path generated by the upstream derive.
Cover every route#
When OpenAPI is enabled, other controllers in the same binary must also provide metadata or #[openapi(skip)]. In the example, the document endpoint excludes itself from its own document.
OpenApiService can be resolved in the constructor, but do not read json or snapshot there. The document is attached after all routes have been prepared. Read it in an action or after build.
Document access and UI#
Your application chooses the JSON endpoint's authentication policy. If you want Swagger UI, host its files separately and connect it to this endpoint. OpenAPI security metadata does not replace a running guard; see schemas and security.
Sources for this page v0.1.0
This guide is based on the reviewed framework commit.