fraiseql_core/lib.rs
1//! # FraiseQL Core
2//!
3//! Core execution engine for FraiseQL v2 - A compiled GraphQL execution engine.
4
5//! ## Architecture
6//!
7//! FraiseQL v2 compiles GraphQL schemas into optimized SQL execution plans at build time,
8//! eliminating runtime overhead and enabling deterministic, high-performance query execution.
9//!
10//! ### Key Components
11//!
12//! - **Schema**: Compiled schema representation (types, fields, SQL mappings)
13//! - **Compiler**: Parsing, validation, and runtime sub-modules (aggregation, fact tables, window
14//! functions)
15//! - **Runtime**: Compiled query executor
16//! - **Database**: Connection pooling and transaction management
17//! - **Cache**: Query result caching with coherency
18//! - **Security**: Authentication, authorization, and audit
19//! - **APQ**: Automatic Persisted Queries
20//!
21//! ## Compilation Flow
22//!
23//! ```text
24//! Python/TypeScript Decorators
25//! ↓
26//! JSON Schema
27//! ↓
28//! SchemaConverter (fraiseql-cli)
29//! ↙ ↓ ↘
30//! Parse Validate Convert
31//! ↓
32//! CompiledSchema.json
33//! ↓
34//! Runtime
35//! ↙ ↓ ↘
36//! Match Execute Project
37//! ↓
38//! GraphQL Response
39//! ```
40//!
41//! ## Example
42//!
43//! ```no_run
44//! // Requires: a compiled schema file and a live PostgreSQL database.
45//! // See: tests/integration/ for runnable examples.
46//! use fraiseql_core::schema::CompiledSchema;
47//! use fraiseql_core::runtime::Executor;
48//! use fraiseql_core::db::postgres::PostgresAdapter;
49//! use std::sync::Arc;
50//!
51//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
52//! # let schema_json = r#"{"types":[],"queries":[]}"#;
53//! // Load compiled schema
54//! let schema = CompiledSchema::from_json(schema_json, false)?;
55//!
56//! // Create executor (db_pool is a DatabaseAdapter implementation)
57//! let db_pool = Arc::new(PostgresAdapter::new("postgresql://localhost/mydb").await?);
58//! let executor = Executor::new(schema, db_pool);
59//!
60//! // Execute query
61//! let query = r#"query { users { id name } }"#;
62//! let result = executor.execute(query, None).await?;
63//!
64//! println!("{}", result);
65//! # Ok(())
66//! # }
67//! ```
68
69#![forbid(unsafe_code)]
70
71// Core modules
72pub mod error;
73pub mod http;
74pub mod schema;
75
76// Compilation layer
77pub mod compiler;
78
79// Execution layer
80pub mod runtime;
81
82// GraphQL parsing and query processing
83pub mod graphql;
84
85// Infrastructure
86pub mod apq;
87pub mod cache;
88
89/// The `chrono` this crate's public API is built against (#1198).
90pub use chrono;
91/// The `deadpool_postgres` this crate's public API is built against (#1198).
92pub use deadpool_postgres;
93/// Core's own handle on the database layer.
94///
95/// Private on purpose. The *public* `db` module below is a curated subset, and core
96/// must not be forced to widen that subset merely to reach something for itself —
97/// which is what a single shared re-export would do, and is how the blanket export
98/// came to expose the whole data plane.
99pub(crate) use fraiseql_db as backend;
100
101/// The database layer this crate's public API is built against.
102///
103/// **Enumerated, not a blanket `pub use fraiseql_db as db;`** (S3 of the boundary
104/// work). The blanket form made every item in `fraiseql-db` nameable from any crate
105/// that depends on `fraiseql-core` — including the data-plane surface the write
106/// chokepoint sits above. Narrowing it is compiler-verified: an item that is not
107/// listed is a compile error at the point of use, not a lint that has to be written
108/// and then kept in step.
109///
110/// Adding a line here widens the surface that transports can reach around the
111/// engine with. Add one only for a type a transport genuinely needs to *name* —
112/// configuration, a trait bound, a value in a signature — never to reach a method.
113pub mod db {
114 pub use fraiseql_db::{
115 // The admin-SQL route's own request/response types (an explicit admin API,
116 // not a request-path surface).
117 AdminSqlOutcome,
118 AdminSqlRequest,
119 dialect::{self, PostgresDialect},
120 // The runtime's own identifier quoting, so the boot-time `sql_source` probe
121 // (#487) and the runtime cannot drift on how a name is rendered.
122 identifier::quote_postgres_identifier,
123 // Introspection, as the CLI's schema tooling consumes it.
124 introspector::{self, RelationInfo, RelationKind},
125 // JSONB path escaping and projection SQL, which the CLI's generators and the
126 // projection parity tests build against.
127 path_escape,
128 projection_generator::{self, PostgresProjectionGenerator},
129 // The traits a transport bounds on, and the types that appear in those bounds.
130 // `ResultCacheStats` is here as the return type of `Executor::result_cache_stats`,
131 // not as a way to reach the cache: the executor mediates every operation on it.
132 traits::{
133 self, ArcDatabaseAdapter, CursorValue, DatabaseAdapter, RelayDatabaseAdapter,
134 ResultCacheStats, WriteMode, WriteRequest, Writer,
135 },
136 types::{
137 self, DatabaseType, JsonbValue, PoolMetrics, QueryStatEntry,
138 sql_hints::{OrderByClause, RelevanceOrder, ScalarFieldType},
139 },
140 // One naming helper, not the whole `utils` module: a pure string function the
141 // REST search handler needs, with no reach into the data plane.
142 utils::to_snake_case,
143 // WHERE construction, which the server builds for REST and gRPC filters.
144 where_clause::{self, WhereClause, WhereOperator},
145 where_generator,
146 where_sql_generator::{self, WhereSqlGenerator},
147 };
148 /// The wire backend, behind the same feature that gates it in `fraiseql-db`.
149 #[cfg(feature = "wire-backend")]
150 pub use fraiseql_db::{FraiseWireAdapter, wire_pool};
151 /// The PostgreSQL backend, behind the same feature that gates it in `fraiseql-db`.
152 ///
153 /// `PostgresAdapter` belongs here, not in the unconditional list above. The
154 /// blanket `pub use fraiseql_db as db;` carried each item's own `#[cfg]` for
155 /// free; enumerating the names drops that, so every line above is an assertion
156 /// that the item is ungated in `fraiseql-db` — and nothing but a feature-OFF
157 /// build checks it. `make lint-feature-matrix` is that build.
158 #[cfg(feature = "postgres")]
159 pub use fraiseql_db::{PostgresAdapter, PostgresIntrospector, postgres};
160}
161
162/// The `graphql_parser` this crate's public API is built against (#1198).
163pub use graphql_parser;
164/// The `indexmap` this crate's public API is built against (#1198).
165pub use indexmap;
166/// The `jsonwebtoken` this crate's public API is built against (#1198).
167pub use jsonwebtoken;
168/// The `regex` this crate's public API is built against (#1198).
169pub use regex;
170/// The `reqwest` this crate's public API is built against (#1198).
171pub use reqwest;
172/// The `serde_json` this crate's public API is built against (#1198).
173pub use serde_json;
174/// The `tokio_postgres` this crate's public API is built against (#1198).
175pub use tokio_postgres;
176/// The `tracing` this crate's public API is built against (#1198).
177pub use tracing;
178#[cfg(feature = "schema-lint")]
179pub mod design;
180#[cfg(feature = "federation")]
181pub use fraiseql_federation as federation;
182pub mod security;
183pub mod tenancy;
184pub mod types;
185pub mod utils;
186pub mod validation;
187
188pub mod prelude;
189
190// Re-exports for convenience
191pub use error::{FraiseQLError, Result};
192pub use schema::CompiledSchema;
193pub use tenancy::TenantContext;
194/// The `uuid` this crate's public API is built against (#1198).
195pub use uuid;
196/// The `zeroize` this crate's public API is built against (#1198).
197pub use zeroize;
198
199/// Version of the FraiseQL core library
200pub const VERSION: &str = env!("CARGO_PKG_VERSION");
201
202/// Minimum supported Rust version
203pub const MSRV: &str = "1.88";