stately_arrow/api/
openapi.rs

1//! `OpenAPI` documentation for the stately-arrow API.
2//!
3//! This module provides the `OpenAPI` specification with conditional schema inclusion
4//! based on enabled features (`database`, `object-store`, etc.).
5
6use utoipa::openapi::tag::TagBuilder;
7use utoipa::openapi::{ComponentsBuilder, InfoBuilder, OpenApiBuilder, PathsBuilder};
8
9use crate::backend::{BackendMetadata, Capability, ConnectionKind, ConnectionMetadata};
10use crate::context::SessionCapability;
11use crate::request::{
12    ConnectionDetailsRequest, ConnectionSearchQuery, ConnectionSearchTerm, QueryRequest,
13};
14use crate::response::{ConnectionDetailsResponse, ListSummary, TableSummary};
15
16/// `OpenAPI` documentation struct for the stately-arrow API.
17#[derive(Clone, Copy)]
18pub struct OpenApiDoc;
19
20impl utoipa::OpenApi for OpenApiDoc {
21    #[allow(unused_mut)]
22    fn openapi() -> utoipa::openapi::OpenApi {
23        // Build components with base schemas
24        let mut components = ComponentsBuilder::new()
25            // Base schemas (always included)
26            .schema_from::<QueryRequest>()
27            .schema_from::<ConnectionSearchTerm>()
28            .schema_from::<ConnectionSearchQuery>()
29            .schema_from::<ConnectionDetailsRequest>()
30            .schema_from::<ConnectionDetailsResponse>()
31            .schema_from::<SessionCapability>()
32            .schema_from::<Capability>()
33            .schema_from::<ConnectionMetadata>()
34            .schema_from::<BackendMetadata>()
35            .schema_from::<ListSummary>()
36            .schema_from::<TableSummary>()
37            .schema_from::<ConnectionKind>()
38            .schema_from::<stately::ApiError>()
39            // Responses
40            .response_from::<ConnectionDetailsResponse>()
41            .response_from::<ListSummary>()
42            .response_from::<TableSummary>();
43
44        // Registry feature schemas
45        #[cfg(feature = "registry")]
46        {
47            use crate::registry::generic::{Connector, RegistryOptions, Type};
48
49            components = components
50                .schema_from::<Connector>()
51                .schema_from::<RegistryOptions>()
52                .schema_from::<Type>();
53        }
54
55        // Database feature schemas
56        #[cfg(feature = "database")]
57        {
58            use crate::database::{
59                Config as DatabaseConfig, ConnectionOptions, Database, PoolOptions, Secret,
60                TlsOptions,
61            };
62            components = components
63                .schema_from::<DatabaseConfig>()
64                .schema_from::<ConnectionOptions>()
65                .schema_from::<Database>()
66                .schema_from::<PoolOptions>()
67                .schema_from::<Secret>()
68                .schema_from::<TlsOptions>();
69
70            // ClickHouse-specific schemas (nested under database feature)
71            #[cfg(feature = "clickhouse")]
72            {
73                use crate::database::clickhouse::{ClickHouseCompression, ClickHouseConfig};
74                components = components
75                    .schema_from::<ClickHouseConfig>()
76                    .schema_from::<ClickHouseCompression>();
77            }
78        }
79
80        // Object store feature schemas
81        #[cfg(feature = "object-store")]
82        {
83            use crate::object_store::{
84                Config as ObjectStoreConfig, ObjectStore, ObjectStoreFormat, ObjectStoreOptions,
85            };
86            components = components
87                .schema_from::<ObjectStoreConfig>()
88                .schema_from::<ObjectStore>()
89                .schema_from::<ObjectStoreOptions>()
90                .schema_from::<ObjectStoreFormat>();
91        }
92
93        // Build paths from handler functions
94        let paths = PathsBuilder::new()
95            .path_from::<super::handlers::__path_list_connectors>()
96            .path_from::<super::handlers::__path_list_catalogs>()
97            .path_from::<super::handlers::__path_list_registered>()
98            .path_from::<super::handlers::__path_connector_list>()
99            .path_from::<super::handlers::__path_connector_list_many>()
100            .path_from::<super::handlers::__path_execute_query>()
101            .path_from::<super::handlers::__path_register>()
102            .build();
103
104        // Build the OpenAPI spec
105        OpenApiBuilder::new()
106            .info(
107                InfoBuilder::new()
108                    .title(env!("CARGO_PKG_NAME"))
109                    .version(env!("CARGO_PKG_VERSION"))
110                    .description(Some(env!("CARGO_PKG_DESCRIPTION")))
111                    .build(),
112            )
113            .paths(paths)
114            .components(Some(components.build()))
115            .tags(Some(vec![
116                TagBuilder::new().name("arrow").description(Some("Arrow data endpoints")).build(),
117            ]))
118            .build()
119    }
120}