Skip to main content

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";