Skip to main content

armature_openapi/
lib.rs

1//! OpenAPI 3.0 specification generation and Swagger UI integration for Armature
2//!
3//! This crate provides tools for generating OpenAPI specifications and serving
4//! interactive API documentation via Swagger UI.
5//!
6//! ## Features
7//!
8//! - 📝 **Programmatic API** - Build OpenAPI specs with fluent builder
9//! - 📊 **Swagger UI response helper** - `swagger_ui_response` renders an interactive
10//!   Swagger UI page, loading its JS/CSS assets from a CDN (not self-contained; requires
11//!   network access and is incompatible with a strict CSP)
12//! - 📤 **JSON/YAML Export** - Multiple export formats
13//! - 🔒 **Type-Safe** - Strongly typed OpenAPI 3.0 specification
14//! - 🔐 **Auth Schemes** - Bearer, API Key, OAuth2, OpenID Connect
15//! - 📋 **Schema Support** - Request/response schemas
16//!
17//! ## Quick Start - Basic API Spec
18//!
19//! ```
20//! use armature_openapi::OpenApiBuilder;
21//!
22//! let spec = OpenApiBuilder::new("My API", "1.0.0")
23//!     .description("A wonderful API")
24//!     .server("http://localhost:3000", None)
25//!     .build();
26//!
27//! assert_eq!(spec.info.title, "My API");
28//! assert_eq!(spec.info.version, "1.0.0");
29//! assert_eq!(spec.servers.len(), 1);
30//! ```
31//!
32//! ## Adding Authentication
33//!
34//! ```
35//! use armature_openapi::{OpenApiBuilder, ApiKeyLocation};
36//!
37//! let spec = OpenApiBuilder::new("Secure API", "1.0.0")
38//!     .add_bearer_auth("bearer")
39//!     .add_api_key_auth("api_key", "X-API-Key", ApiKeyLocation::Header)
40//!     .build();
41//!
42//! assert!(spec.components.is_some());
43//! let components = spec.components.unwrap();
44//! assert!(components.security_schemes.contains_key("bearer"));
45//! assert!(components.security_schemes.contains_key("api_key"));
46//! ```
47//!
48//! ## Adding Paths and Operations
49//!
50//! ```
51//! use armature_openapi::{OpenApiBuilder, PathItem, Operation, Response};
52//! use std::collections::HashMap;
53//!
54//! let mut get_operation = Operation::default();
55//! get_operation.summary = Some("Get user by ID".to_string());
56//! get_operation.operation_id = Some("getUserById".to_string());
57//!
58//! let mut responses = HashMap::new();
59//! responses.insert("200".to_string(), Response {
60//!     description: "Successful response".to_string(),
61//!     content: None,
62//! });
63//! get_operation.responses = responses;
64//!
65//! let mut path_item = PathItem::default();
66//! path_item.get = Some(get_operation);
67//!
68//! let mut spec = OpenApiBuilder::new("User API", "1.0.0").build();
69//! spec.paths.insert("/users/{id}".to_string(), path_item);
70//!
71//! assert!(spec.paths.contains_key("/users/{id}"));
72//! assert!(spec.paths.get("/users/{id}").unwrap().get.is_some());
73//! ```
74//!
75//! ## Swagger UI Configuration
76//!
77//! ```
78//! use armature_openapi::{OpenApiBuilder, SwaggerConfig};
79//!
80//! let spec = OpenApiBuilder::new("My API", "1.0.0")
81//!     .description("API with Swagger UI")
82//!     .build();
83//!
84//! let swagger_config = SwaggerConfig::new("/api-docs", spec)
85//!     .with_title("My API Documentation");
86//!
87//! // Configuration ready
88//! assert_eq!(swagger_config.path, "/api-docs");
89//! assert_eq!(swagger_config.title, "My API Documentation");
90//! ```
91//!
92//! ## Adding Multiple Servers
93//!
94//! ```
95//! use armature_openapi::OpenApiBuilder;
96//!
97//! let spec = OpenApiBuilder::new("Multi-Env API", "1.0.0")
98//!     .server("https://api.production.com", Some("Production server".to_string()))
99//!     .server("https://api.staging.com", Some("Staging server".to_string()))
100//!     .server("http://localhost:3000", Some("Local development".to_string()));
101//!
102//! let built_spec = spec.build();
103//!
104//! assert_eq!(built_spec.servers.len(), 3);
105//! assert_eq!(built_spec.servers[0].url, "https://api.production.com");
106//! assert_eq!(built_spec.servers[1].url, "https://api.staging.com");
107//! assert_eq!(built_spec.servers[2].url, "http://localhost:3000");
108//! assert_eq!(built_spec.servers[0].description, Some("Production server".to_string()));
109//! ```
110//!
111//! ## README Quick Start
112//!
113//! This mirrors the example in `README.md` verbatim, so it is guaranteed to compile.
114//!
115//! ```
116//! use armature_openapi::{OpenApiBuilder, SwaggerConfig, swagger_ui_response, spec_json_response};
117//!
118//! // Build the spec by hand with the fluent builder.
119//! let spec = OpenApiBuilder::new("My API", "1.0.0")
120//!     .description("A wonderful API")
121//!     .server("http://localhost:3000", None)
122//!     .build();
123//!
124//! // Wrap it in a SwaggerConfig to serve it.
125//! let config = SwaggerConfig::new("/api-docs", spec).with_title("My API Documentation");
126//!
127//! // `swagger_ui_response(&config)` returns an `HttpResponse` rendering the Swagger UI HTML page.
128//! // `spec_json_response(&config)` returns an `HttpResponse` serving the raw spec as JSON.
129//! let ui_response = swagger_ui_response(&config).unwrap();
130//! let json_response = spec_json_response(&config).unwrap();
131//!
132//! assert_eq!(config.path, "/api-docs");
133//! assert_eq!(config.title, "My API Documentation");
134//! assert_eq!(ui_response.status, 200);
135//! assert_eq!(json_response.status, 200);
136//! ```
137
138pub mod builder;
139pub mod playground;
140pub mod spec;
141pub mod swagger;
142
143pub use builder::*;
144pub use playground::*;
145pub use spec::*;
146pub use swagger::*;