fraiseql_server/routes/api/schema.rs
1//! Schema export API endpoints.
2//!
3//! Provides endpoints for:
4//! - Exporting compiled schema as GraphQL SDL (Schema Definition Language)
5//! - Exporting schema as JSON for programmatic access
6
7use axum::{
8 Json,
9 extract::State,
10 http::StatusCode,
11 response::{IntoResponse, Response},
12};
13use fraiseql_core::db::traits::DatabaseAdapter;
14use serde::Serialize;
15
16use crate::routes::{
17 api::types::{ApiError, ApiResponse},
18 graphql::AppState,
19};
20
21/// Response containing GraphQL SDL schema.
22#[derive(Debug, Serialize)]
23pub struct GraphQLSchemaResponse {
24 /// GraphQL Schema Definition Language (SDL) representation
25 pub schema: String,
26}
27
28/// Response containing JSON-formatted schema.
29#[derive(Debug, Serialize)]
30pub struct JsonSchemaResponse {
31 /// Compiled schema as JSON object
32 pub schema: serde_json::Value,
33}
34
35/// Export compiled schema as GraphQL SDL.
36///
37/// Returns the schema in GraphQL Schema Definition Language (SDL) format.
38/// This is human-readable and suitable for documentation, tools, and introspection.
39///
40/// Response format: `text/plain` (not JSON wrapped)
41///
42/// # Errors
43///
44/// This handler currently always succeeds; it is infallible.
45pub async fn export_sdl_handler<A: DatabaseAdapter>(
46 State(state): State<AppState<A>>,
47) -> Result<Response, ApiError> {
48 let schema_sdl = state.executor().schema().raw_schema();
49 Ok((StatusCode::OK, schema_sdl).into_response())
50}
51
52/// Export compiled schema as JSON.
53///
54/// Returns the full compiled schema in JSON format.
55/// This includes type information, field definitions, and metadata.
56/// Useful for programmatic access and tooling.
57///
58/// Response format: Standard JSON API response with data wrapper
59///
60/// # Errors
61///
62/// Returns `ApiError` with an internal error if the schema cannot be serialized to JSON.
63pub async fn export_json_handler<A: DatabaseAdapter>(
64 State(state): State<AppState<A>>,
65) -> Result<Json<ApiResponse<JsonSchemaResponse>>, ApiError> {
66 let schema_json = serde_json::to_value(state.executor().schema())
67 .map_err(|e| ApiError::internal_error(format!("Failed to serialize schema: {e}")))?;
68
69 let response = JsonSchemaResponse {
70 schema: schema_json,
71 };
72
73 Ok(Json(ApiResponse {
74 status: "success".to_string(),
75 data: response,
76 }))
77}