rustapi_openapi/
lib.rs

1//! OpenAPI documentation for RustAPI
2//!
3//! This crate provides OpenAPI specification generation and Swagger UI serving
4//! for RustAPI applications. It wraps `utoipa` internally while providing a
5//! clean public API.
6//!
7//! # Features
8//!
9//! - Automatic OpenAPI spec generation
10//! - Swagger UI serving at `/docs`
11//! - JSON spec at `/openapi.json`
12//! - Schema derivation via `#[derive(Schema)]`
13//!
14//! # Usage
15//!
16//! ```rust,ignore
17//! use rustapi_rs::prelude::*;
18//!
19//! #[derive(Serialize, Schema)]
20//! struct User {
21//!     id: i64,
22//!     name: String,
23//! }
24//!
25//! RustApi::new()
26//!     .route("/users", get(list_users))
27//!     .docs("/docs")
28//!     .run("127.0.0.1:8080")
29//!     .await
30//! ```
31
32mod config;
33mod schemas;
34mod spec;
35#[cfg(feature = "swagger-ui")]
36mod swagger;
37
38pub use config::OpenApiConfig;
39pub use schemas::{
40    ErrorBodySchema, ErrorSchema, FieldErrorSchema, ValidationErrorBodySchema,
41    ValidationErrorSchema,
42};
43pub use spec::{
44    ApiInfo, MediaType, OpenApiSpec, Operation, OperationModifier, Parameter, PathItem,
45    RequestBody, ResponseModifier, ResponseSpec, SchemaRef,
46};
47
48// Re-export utoipa's ToSchema derive macro as Schema
49pub use utoipa::ToSchema as Schema;
50// Re-export utoipa's IntoParams derive macro
51pub use utoipa::IntoParams;
52
53// Re-export utoipa types for advanced usage
54pub mod utoipa_types {
55    pub use utoipa::{openapi, IntoParams, Modify, OpenApi, ToSchema};
56}
57
58use bytes::Bytes;
59use http::{header, Response, StatusCode};
60use http_body_util::Full;
61
62/// Generate OpenAPI JSON response
63pub fn openapi_json(spec: &OpenApiSpec) -> Response<Full<Bytes>> {
64    match serde_json::to_string_pretty(&spec.to_json()) {
65        Ok(json) => Response::builder()
66            .status(StatusCode::OK)
67            .header(header::CONTENT_TYPE, "application/json")
68            .body(Full::new(Bytes::from(json)))
69            .unwrap(),
70        Err(_) => Response::builder()
71            .status(StatusCode::INTERNAL_SERVER_ERROR)
72            .body(Full::new(Bytes::from("Failed to serialize OpenAPI spec")))
73            .unwrap(),
74    }
75}
76
77/// Generate Swagger UI HTML response
78#[cfg(feature = "swagger-ui")]
79pub fn swagger_ui_html(openapi_url: &str) -> Response<Full<Bytes>> {
80    let html = swagger::generate_swagger_html(openapi_url);
81    Response::builder()
82        .status(StatusCode::OK)
83        .header(header::CONTENT_TYPE, "text/html; charset=utf-8")
84        .body(Full::new(Bytes::from(html)))
85        .unwrap()
86}