pub struct CompiledSchema {Show 36 fields
pub types: Vec<TypeDefinition>,
pub enums: Vec<EnumDefinition>,
pub input_types: Vec<InputObjectDefinition>,
pub interfaces: Vec<InterfaceDefinition>,
pub unions: Vec<UnionDefinition>,
pub queries: Vec<QueryDefinition>,
pub mutations: Vec<MutationDefinition>,
pub subscriptions: Vec<SubscriptionDefinition>,
pub directives: Vec<DirectiveDefinition>,
pub fact_tables: HashMap<String, FactTableMetadata>,
pub observers: Vec<ObserverDefinition>,
pub sources: Vec<SourceDefinition>,
pub subscribable: Vec<SubscribableEntity>,
pub operation_cost_weights: HashMap<String, usize>,
pub federation: Option<FederationConfig>,
pub security: Option<SecurityConfig>,
pub auth: Option<AuthClientConfig>,
pub observers_config: Option<ObserversConfig>,
pub subscriptions_config: Option<SubscriptionsConfig>,
pub validation_config: Option<ValidationConfig>,
pub debug_config: Option<DebugConfig>,
pub mcp_config: Option<McpConfig>,
pub rest_config: Option<RestConfig>,
pub grpc_config: Option<GrpcConfig>,
pub changelog: Option<ChangelogConfig>,
pub session_variables: SessionVariablesConfig,
pub hierarchies_config: Option<HierarchiesConfig>,
pub naming_convention: NamingConvention,
pub naming_acronyms: Vec<String>,
pub fraiseql_version: ProducerVersion,
pub schema_sdl: Option<String>,
pub custom_scalars: CustomTypeRegistry,
pub query_index: HashMap<String, usize>,
pub mutation_index: HashMap<String, usize>,
pub subscription_index: HashMap<String, usize>,
pub where_relation_fields: RelationFieldMaps,
}Expand description
Complete compiled schema - all type information for serving.
This is the central type that holds the entire GraphQL schema after compilation from any supported authoring language.
§Example
use fraiseql_core::schema::CompiledSchema;
let json = r#"{
"types": [],
"queries": [],
"mutations": [],
"subscriptions": []
}"#;
let schema = CompiledSchema::from_json(json, false).unwrap();
assert_eq!(schema.types.len(), 0);Fields§
§types: Vec<TypeDefinition>GraphQL object type definitions.
enums: Vec<EnumDefinition>GraphQL enum type definitions.
input_types: Vec<InputObjectDefinition>GraphQL input object type definitions.
interfaces: Vec<InterfaceDefinition>GraphQL interface type definitions.
unions: Vec<UnionDefinition>GraphQL union type definitions.
queries: Vec<QueryDefinition>GraphQL query definitions.
mutations: Vec<MutationDefinition>GraphQL mutation definitions.
subscriptions: Vec<SubscriptionDefinition>GraphQL subscription definitions.
directives: Vec<DirectiveDefinition>Custom directive definitions. These are user-defined directives beyond the built-in @skip, @include, @deprecated.
fact_tables: HashMap<String, FactTableMetadata>Fact table metadata (for analytics queries).
Key: table name (e.g., tf_sales)
observers: Vec<ObserverDefinition>Observer definitions (database change event listeners).
sources: Vec<SourceDefinition>Scheduled ingress source definitions (#573) — the dual of observers.
Each runs its function on a cron schedule, pulling from an external system
into the database via mutations with a durable cursor. Empty (and omitted
from the compiled JSON) when no source is declared, so a schema that predates
this field deserializes and re-serializes byte-for-byte unchanged.
subscribable: Vec<SubscribableEntity>@subscribable declarations (#366): GraphQL types whose underlying
table(s) get the shipped external-write capture trigger.
Aggregated by the compiler from each type’s @subscribable(tables=[...])
annotation; consumed by
generate_capture_trigger_ddl
to emit per-table capture triggers. Empty (and omitted from the compiled
JSON) when no type is subscribable — so a schema that predates this field
deserializes and re-serializes byte-for-byte unchanged.
operation_cost_weights: HashMap<String, usize>Per-operation @cost(weight: N) overrides (#379): root query/mutation name
→ manual cost weight, consulted by the runtime per-tenant cost-budget check
(estimate_query_cost) so a top-level operation counts as exactly N
instead of its walked subtree complexity. Aggregated by the compiler from
each operation’s @cost annotation. Empty (and omitted from the compiled
JSON) when no operation carries @cost — so a schema that predates this
field deserializes and re-serializes byte-for-byte unchanged.
federation: Option<FederationConfig>Federation metadata for Apollo Federation v2 support.
security: Option<SecurityConfig>Security configuration (from fraiseql.toml).
auth: Option<AuthClientConfig>PKCE OAuth-client configuration for server-side login ([auth] PKCE group).
Carries the OIDC client identity (client_id, client_secret_env,
server_redirect_uri) and the provider’s discovery_url. The runtime
resolves the authorization_endpoint / token_endpoint by fetching the
discovery document at boot from discovery_url (#621) — the compiler
stays hermetic and the discovery document is always fresh. None when the
[auth] PKCE client group is absent.
observers_config: Option<ObserversConfig>Observers/event system configuration (from fraiseql.toml).
Contains backend connection settings (redis_url, nats_url, etc.) and
event handler definitions compiled from the [observers] TOML section.
subscriptions_config: Option<SubscriptionsConfig>WebSocket subscription configuration (hooks, limits).
Compiled from the [subscriptions] TOML section.
validation_config: Option<ValidationConfig>Query validation config (depth/complexity limits).
Compiled from the [validation] TOML section.
debug_config: Option<DebugConfig>Debug/development configuration.
Compiled from the [debug] TOML section.
mcp_config: Option<McpConfig>MCP (Model Context Protocol) server configuration.
Compiled from the [mcp] TOML section.
rest_config: Option<RestConfig>REST transport configuration.
Compiled from the [rest] TOML section.
grpc_config: Option<GrpcConfig>gRPC transport configuration.
Compiled from the [grpc] TOML section.
changelog: Option<ChangelogConfig>Changelog GraphQL-exposure configuration.
Compiled from the [changelog] TOML section. When present with
expose = true, the compiler injects the EntityChangeLog /
TransportCheckpoint types plus their cursor query, point-lookup query, and
checkpoint upsert mutation. None when the block is absent (the default).
session_variables: SessionVariablesConfigSession variable injection configuration.
When populated, the executor calls PostgreSQL set_config() before each
mutation, injecting per-request values (JWT claims, HTTP headers, literals)
as transaction-scoped settings. SQL functions read these via
current_setting('app.tenant_id', true).
Compiled from the [session_variables] TOML section.
hierarchies_config: Option<HierarchiesConfig>Hierarchy definitions for ID-based ltree operators.
Maps hierarchy names to table/path_column pairs. Compiled from the
[hierarchies] TOML section. Used at runtime to resolve HierarchyContext
for descendantOfId / ancestorOfId WHERE clause generation.
naming_convention: NamingConventionNaming convention for GraphQL operation names.
When set to CamelCase, operation names are converted from snake_case
(e.g., create_dns_server → createDnsServer) in the introspection
schema and lookup indexes. Compiled from [fraiseql] in fraiseql.toml.
naming_acronyms: Vec<String>Acronyms whose internal digit stays attached when resolving a GraphQL field
name back to its snake_case JSONB key (e.g. s3, ipv4, oauth2). Added
to the built-in defaults at boot via fraiseql_db::utils::set_runtime_acronyms.
Skipped when empty so a schema with no project acronyms serializes byte-for-byte
as before this field existed (no schema-hash churn; back-compat on load).
fraiseql_version: ProducerVersionThe fraiseql build that produced this compiled schema (#1304).
Checked by validate_producer_version
at every seam that turns an artifact into a running executor. Anything
this build did not produce is refused, including an artifact that names
no build at all.
schema_sdl: Option<String>Raw GraphQL schema as string (for SDL generation).
custom_scalars: CustomTypeRegistryCustom scalar type registry.
Contains definitions for custom scalar types defined in the schema.
Built during code generation from IRScalar definitions.
Not serialized - populated at runtime from ir.scalars.
query_index: HashMap<String, usize>O(1) lookup index: query name → index into self.queries.
Built at construction time by build_indexes(); not serialized.
Populated automatically by from_json(); call build_indexes() after
direct mutation of self.queries.
mutation_index: HashMap<String, usize>O(1) lookup index: mutation name → index into self.mutations.
Built at construction time by build_indexes(); not serialized.
Populated automatically by from_json(); call build_indexes() after
direct mutation of self.mutations.
subscription_index: HashMap<String, usize>O(1) lookup index: subscription name → index into self.subscriptions.
Built at construction time by build_indexes(); not serialized.
Populated automatically by from_json(); call build_indexes() after
direct mutation of self.subscriptions.
where_relation_fields: RelationFieldMapsThe where keys of every type a nested predicate can descend into.
A nested where level is adjudicated against the target type’s keys —
{machine: {bogus: {eq: …}}} is refused because MachineWhereInput has
no bogus, rather than lowering to a JSON path that matches nothing.
Built at construction time by build_indexes(); not serialized.
Implementations§
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn fact_table_mapping_violations(&self) -> Vec<String>
pub fn fact_table_mapping_violations(&self) -> Vec<String>
Fact tables that declare one dimension twice, in ways a request could read two
ways (#1231): a native_dimension_mapping key that is also a
denormalized_filters column mapped to a different column, or two mapping keys
naming one dimension (in two casings) mapped to different columns. One message
per conflict, empty when every declaration agrees.
Sourcepub fn fact_table_type(
&self,
metadata: &FactTableMetadata,
) -> Option<&TypeDefinition>
pub fn fact_table_type( &self, metadata: &FactTableMetadata, ) -> Option<&TypeDefinition>
The type a fact table is read as, when it is linked to one that exists.
Sourcepub fn fact_table_link_violations(&self) -> Vec<String>
pub fn fact_table_link_violations(&self) -> Vec<String>
Fact tables whose link to a type cannot be enforced: the type does not exist, or it lacks a name the fact table declares. One message per fact table, empty when every link is enforceable; unlinked fact tables are not concerned.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn federation_key_problems(&self) -> Vec<FederationKeyProblem>
pub fn federation_key_problems(&self) -> Vec<FederationKeyProblem>
Every reason a federation entity’s @key cannot be served as declared (#1395).
Empty when the schema declares no federation block, or every entity is a
declared, non-embedded type or interface whose key selects published fields.
Called from finish_load and from fraiseql compile, so neither path can accept a
key the other would refuse.
Sourcepub fn federation_key_violations(&self) -> Vec<String>
pub fn federation_key_violations(&self) -> Vec<String>
Self::federation_key_problems, one sentence each.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn validate_producer_version(&self) -> Result<(), String>
pub fn validate_producer_version(&self) -> Result<(), String>
Refuse a compiled schema this build did not produce (#1304).
The compiled schema is a build artifact of the fraiseql release that wrote it, so the only artifact whose meaning this runtime can vouch for is its own build’s. The check is an equality, deliberately: a runtime that decided whether another build’s artifact were close enough would be making the judgement #1303 got wrong, silently, on the operator’s behalf.
An artifact carrying no stamp is refused too. It is the older case — nothing this project has shipped since v2.1 omits the field — and accepting it, as the format-version check it replaces did, left the guard admitting the stalest artifacts while refusing merely-stale ones.
§Errors
Returns an operator-facing message naming both builds and the recompile, unless the artifact was produced by this one.
Sourcepub fn add_fact_table(
&mut self,
table_name: String,
metadata: FactTableMetadata,
)
pub fn add_fact_table( &mut self, table_name: String, metadata: FactTableMetadata, )
Register fact table metadata.
§Arguments
table_name- Fact table name (e.g.,tf_sales)metadata- TypedFactTableMetadata
Sourcepub fn get_fact_table(&self, name: &str) -> Option<&FactTableMetadata>
pub fn get_fact_table(&self, name: &str) -> Option<&FactTableMetadata>
Sourcepub fn list_fact_tables(&self) -> Vec<&str>
pub fn list_fact_tables(&self) -> Vec<&str>
Sourcepub fn has_fact_tables(&self) -> bool
pub fn has_fact_tables(&self) -> bool
Check if schema contains any fact tables.
Sourcepub fn find_observer(&self, name: &str) -> Option<&ObserverDefinition>
pub fn find_observer(&self, name: &str) -> Option<&ObserverDefinition>
Find an observer definition by name.
Sourcepub fn find_observers_for_entity(
&self,
entity: &str,
) -> Vec<&ObserverDefinition>
pub fn find_observers_for_entity( &self, entity: &str, ) -> Vec<&ObserverDefinition>
Get all observers for a specific entity type.
Sourcepub fn find_observers_for_event(&self, event: &str) -> Vec<&ObserverDefinition>
pub fn find_observers_for_event(&self, event: &str) -> Vec<&ObserverDefinition>
Get all observers for a specific event type (INSERT, UPDATE, DELETE).
Sourcepub const fn has_observers(&self) -> bool
pub const fn has_observers(&self) -> bool
Check if schema contains any observers.
Sourcepub const fn observer_count(&self) -> usize
pub const fn observer_count(&self) -> usize
Get total number of observers.
Sourcepub fn federation_metadata(&self) -> Option<FederationMetadata>
pub fn federation_metadata(&self) -> Option<FederationMetadata>
Sourcepub fn entity_sources(&self) -> HashMap<String, EntitySource>
pub fn entity_sources(&self) -> HashMap<String, EntitySource>
Build the per-entity-type backing source map (typename →
EntitySource) the federation
_entities resolver reads from instead of guessing lower(typename)
(#504/#507).
Two sources, query-wins:
- Query-sourced (owned entities): the backing relation rides on the root query that
returns the type, keyed by
return_type, first-wins — the same query→type binding the Relaynodepath uses. The query’sjsonb_column(which the compiler defaults to"data") drives jsonb projection. - Type-sourced fallback (#507): an owner-split
extend type … @keyentity resolved in a subgraph that does not own it exposes no root query, so there is nothing in (1) to source its relation from. Its relation instead rides on the type-levelsql_sourcethe compiler carries from the authoring SDK. This only fills gaps — a query-sourced entry always wins.
Both sources read the entity’s jsonb_column the same way: a non-empty column selects
jsonb-projection mode (<col>->'<field>'), an empty one selects flat-column mode (bare
columns). The compiler defaults both a query’s and an extends type’s jsonb_column to the
standard "data" view shape, so a flat-column entity must be authored with an explicit
empty jsonb_column.
Sourcepub fn federation_service_sdl(&self) -> Result<String>
pub fn federation_service_sdl(&self) -> Result<String>
The SDL a federated subgraph serves as _service { sdl }: Apollo Federation v2
directives over the schema’s types (#1427).
The executor’s _service arm and fraiseql federation sdl both call this, so what
a server serves and what the CLI prints from the same artifact cannot differ.
§Errors
FraiseQLError::Validation when the
schema has no enabled [federation] section.
Sourcepub const fn security_config(&self) -> Option<&SecurityConfig>
pub const fn security_config(&self) -> Option<&SecurityConfig>
Get security configuration from schema.
§Returns
Security configuration if present (includes role definitions)
Sourcepub fn is_multi_tenant(&self) -> bool
pub fn is_multi_tenant(&self) -> bool
Returns true if this schema declares a multi-tenant deployment.
Multi-tenant schemas require Row-Level Security (RLS) to be active whenever query result caching is enabled. Without RLS, all tenants sharing the same query parameters would receive the same cached response.
True when [security] multi_tenant = true or a non-none
[tenancy] mode. The second clause is load-bearing: tenancy.mode is the
knob operators actually set, and reading only security.multi_tenant — which
no compile path could produce — left both dependent gates permanently off
(#758).
Sourcepub fn tenancy_mode(&self) -> TenancyMode
pub fn tenancy_mode(&self) -> TenancyMode
Returns the tenancy isolation mode configured for this schema.
Defaults to TenancyMode::None when no security or tenancy configuration
is present, meaning single-tenant operation with no isolation machinery.
Sourcepub fn tenancy_config(&self) -> Option<&TenancyConfig>
pub fn tenancy_config(&self) -> Option<&TenancyConfig>
Returns the tenancy configuration, if present.
Returns None when no security configuration exists. Returns the
default TenancyConfig (mode=none) when security exists but tenancy
is not explicitly configured.
Sourcepub fn tenant_claim(&self) -> &str
pub fn tenant_claim(&self) -> &str
The JWT claim that names a request’s tenant: [fraiseql.tenancy] tenant_claim,
or DEFAULT_TENANT_CLAIM
when the schema declares none.
The one source for every reader of “which claim is the tenant” (#1388): the
compiler bakes it into row-mode jwt:<claim> injects, and the server derives
SecurityContext::tenant_id from it.
Sourcepub fn find_role(&self, role_name: &str) -> Option<RoleDefinition>
pub fn find_role(&self, role_name: &str) -> Option<RoleDefinition>
Sourcepub fn get_role_scopes(&self, role_name: &str) -> Vec<String>
pub fn get_role_scopes(&self, role_name: &str) -> Vec<String>
Sourcepub fn role_has_scope(&self, role_name: &str, scope: &str) -> bool
pub fn role_has_scope(&self, role_name: &str, scope: &str) -> bool
Sourcepub fn has_rls_configured(&self) -> bool
pub fn has_rls_configured(&self) -> bool
Returns true if this schema declares that database Row-Level Security
isolates its data ([security.rls] enabled = true).
Used at server startup to validate that caching is safe for multi-tenant deployments, and to decide whether to verify the declaration against the live database catalog.
This is a declaration, not a proof: FraiseQL does not author RLS policies,
so nothing in the compiled schema can establish that they exist. That is what
CachedDatabaseAdapter::validate_rls_active checks against the real
database (#762).
It previously counted security.additional["policies"] — authorization
policies, not RLS, and a section #612 made a hard compile error — so it
answered false for every schema any supported workflow could produce
(#758).
§Example
use fraiseql_core::schema::CompiledSchema;
let schema = CompiledSchema::default();
assert!(!schema.has_rls_configured());Sourcepub fn raw_schema(&self) -> String
pub fn raw_schema(&self) -> String
Get raw GraphQL schema SDL.
§Returns
Raw schema string if available, otherwise generates from type definitions,
including the root Query/Mutation types.
Root operations are stored in self.queries /
self.mutations rather than as Query/Mutation object
types in self.types, so they are rendered here explicitly.
Omitting them produces an SDL that advertises no root fields — which makes the
federation _service SDL (built from this output) fail gateway composition
with NO_QUERIES.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn declares_enrichment_consumer(&self) -> bool
pub fn declares_enrichment_consumer(&self) -> bool
Whether this schema declares any consumer of enriched identity — a
SessionVariableSource::Enrichment mapping or an
InjectedParamSource::Enrichment parameter (#539).
Computed rather than cached: a cached flag would default to false on any
schema that skipped build_indexes, and a security backstop that switches
itself off on a hand-built fixture is worse than none. The scan is two
iterator passes over declarations, run once per executor construction.
⚠ This answers “does anything read enriched identity”, which is not the same question as “must this request resolve”. Resolution is enforced by the transport’s producer seam and runs whenever a resolver is configured, whether or not anything reads the result — making the fail-closed boundary conditional on a declaration is precisely the silent-skip the design fights. This is read only by the engine’s backstop, which asks a narrower question: “may a principal that never met a resolver execute here”.
Sourcepub fn build_indexes(&mut self)
pub fn build_indexes(&mut self)
Build the schema’s derived state: O(1) operation lookup indexes, and the
filter/sort input surface where/orderBy are typed against.
Called automatically by from_json(). Must be called manually after any
direct mutation of self.queries, self.mutations, or self.subscriptions.
§The derived filter surface
derived_inputs::derive emits {Entity}WhereInput,
{Entity}OrderByInput and their leaf filters; they are appended to
input_types/enums so introspection, the federation SDL, § 5.8.2 and
the client emitters all read one materialised surface rather than four
re-derivations of it. Nothing is overwritten — a name the author declared
is never derived over — which is also what makes a second call inert.
They are deliberately not part of the compiled artifact. The where
and orderBy arguments themselves are synthesized at read time from
auto_params rather than
stored; their types follow the same rule, so a schema compiled by an
older CLI gains the surface on load and the artifact’s content hash does
not move.
A bare serde_json::from_str::<CompiledSchema> skips this, as it always
has for the operation indexes. The consequence is a degraded surface,
never a wrong one: graphql_arguments types an argument only when the
schema carries the type, so a schema that was never built falls back to
JSON rather than naming something undefined. Load through
from_json to get the typed surface.
Sourcepub fn display_name(&self, name: &str) -> String
pub fn display_name(&self, name: &str) -> String
Return the display name for an operation, applying the naming convention.
When naming_convention is CamelCase, converts snake_case names to
camelCase (e.g., create_dns_server → createDnsServer).
When Preserve, returns the name unchanged.
Sourcepub fn find_type(&self, name: &str) -> Option<&TypeDefinition>
pub fn find_type(&self, name: &str) -> Option<&TypeDefinition>
Find a type definition by name.
Sourcepub fn type_has_gated_field(&self, type_name: &str) -> bool
pub fn type_has_gated_field(&self, type_name: &str) -> bool
Whether the named type has any policy-gated field
(FieldDefinition::authorize).
Used by projection paths that do not (yet) run the dynamic field authorizer to fail closed conservatively when a gated type could be projected (#423).
Whether any object type in the schema declares a policy-gated field (#423).
Used by projection paths with a dynamic/unknown result type (Relay node,
federation _entities) to fail closed when field-level authorization is in
use but cannot yet be enforced on that path.
Sourcepub fn find_enum(&self, name: &str) -> Option<&EnumDefinition>
pub fn find_enum(&self, name: &str) -> Option<&EnumDefinition>
Find an enum definition by name.
Sourcepub fn find_input_type(&self, name: &str) -> Option<&InputObjectDefinition>
pub fn find_input_type(&self, name: &str) -> Option<&InputObjectDefinition>
Find an input object definition by name.
Sourcepub fn find_interface(&self, name: &str) -> Option<&InterfaceDefinition>
pub fn find_interface(&self, name: &str) -> Option<&InterfaceDefinition>
Find an interface definition by name.
Sourcepub fn find_implementors(&self, interface_name: &str) -> Vec<&TypeDefinition>
pub fn find_implementors(&self, interface_name: &str) -> Vec<&TypeDefinition>
Find all types that implement a given interface.
Sourcepub fn find_union(&self, name: &str) -> Option<&UnionDefinition>
pub fn find_union(&self, name: &str) -> Option<&UnionDefinition>
Find a union definition by name.
Sourcepub fn success_types(&self, return_type: &str) -> Vec<String>
pub fn success_types(&self, return_type: &str) -> Vec<String>
The types a successful mutation returning return_type can produce: the non-error
members of a union, the implementors of an interface, or the type itself.
The one answer to “what entity does this mutation write” — the mutation runner’s
stamp check, the after-mutation dispatcher and the compiler’s trigger
cross-reference all read it, so a synthesized error union (auto_error_union)
cannot rename the entity for one of them and not the others (#1340).
Sourcepub fn find_query(&self, name: &str) -> Option<&QueryDefinition>
pub fn find_query(&self, name: &str) -> Option<&QueryDefinition>
Find a query definition by name.
Uses the O(1) pre-built index when available; falls back to O(n) linear
scan for schemas built directly in tests without calling build_indexes().
If the exact name is not found, retries with to_snake_case(name) to
handle camelCase → snake_case normalization (e.g. dnsServers →
dns_servers). This supports schemas compiled before the SDK camelCase
migration.
Sourcepub fn find_mutation(&self, name: &str) -> Option<&MutationDefinition>
pub fn find_mutation(&self, name: &str) -> Option<&MutationDefinition>
Find a mutation definition by name.
Uses the O(1) pre-built index when available; falls back to O(n) linear
scan for schemas built directly in tests without calling build_indexes().
If the exact name is not found, retries with to_snake_case(name) to
handle camelCase → snake_case normalization. This supports schemas
compiled before the SDK camelCase migration.
Sourcepub fn find_subscription(&self, name: &str) -> Option<&SubscriptionDefinition>
pub fn find_subscription(&self, name: &str) -> Option<&SubscriptionDefinition>
Find a subscription definition by name.
Uses the O(1) pre-built index when available; falls back to O(n) linear
scan for schemas built directly in tests without calling build_indexes().
If the exact name is not found, retries with to_snake_case(name) to
handle camelCase → snake_case normalization. This supports schemas
compiled before the SDK camelCase migration.
Sourcepub fn find_directive(&self, name: &str) -> Option<&DirectiveDefinition>
pub fn find_directive(&self, name: &str) -> Option<&DirectiveDefinition>
Find a custom directive definition by name.
Sourcepub const fn operation_count(&self) -> usize
pub const fn operation_count(&self) -> usize
Get total number of operations (queries + mutations + subscriptions).
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn from_json(
json: &str,
strict_integrity: bool,
) -> Result<Self, FraiseQLError>
pub fn from_json( json: &str, strict_integrity: bool, ) -> Result<Self, FraiseQLError>
Deserialize from JSON string.
This is the primary way to create a schema from any authoring language.
The authoring language emits schema.json; fraiseql-cli compile produces
schema.compiled.json; Rust deserializes and owns the result.
§Integrity Checking
fraiseql-cli compile embeds a _content_hash field (SHA-256 of the compiled JSON
body, first 16 bytes as lowercase hex) in the compiled output. This function
extracts that field, recomputes the hash over the remaining JSON, and compares.
strict_integrity = true: missing or mismatched hash returnsErr.strict_integrity = false: missing hash logs a warning; mismatch logs a warning but proceeds (backwards compatibility for schemas compiled without_content_hash).
§Errors
Returns error if JSON is malformed or doesn’t match schema structure.
§Example
use fraiseql_core::schema::CompiledSchema;
let json = r#"{"types": [], "queries": [], "mutations": [], "subscriptions": []}"#;
let schema = CompiledSchema::from_json(json, false).unwrap();Sourcepub fn to_json(&self) -> Result<String, Error>
pub fn to_json(&self) -> Result<String, Error>
Serialize to JSON string.
§Errors
Returns error if serialization fails (should not happen for valid schema).
Sourcepub fn to_json_pretty(&self) -> Result<String, Error>
pub fn to_json_pretty(&self) -> Result<String, Error>
Serialize to pretty JSON string (for debugging/config files).
§Errors
Returns error if serialization fails.
Sourcepub fn content_hash(&self) -> String
pub fn content_hash(&self) -> String
Returns a 32-character hex SHA-256 content hash of this schema’s canonical JSON.
Use as schema_version when constructing CachedDatabaseAdapter to guarantee
cache invalidation on any schema change, regardless of whether the package
version was bumped.
Two schemas that differ by even one field will produce different hashes. The same schema serialised twice always produces the same hash (stable).
§Panics
Does not panic — CompiledSchema always serialises to valid JSON.
§Example
use fraiseql_core::schema::CompiledSchema;
let schema = CompiledSchema::default();
let hash = schema.content_hash();
assert_eq!(hash.len(), 32); // 16 bytes → 32 hex charsSource§impl CompiledSchema
impl CompiledSchema
Sourcepub fn type_inject_violations(&self) -> Vec<String>
pub fn type_inject_violations(&self) -> Vec<String>
Scoping declarations a type and its backing query make that contradict each other.
Returns one human-readable message per violation, empty when the schema is
enforceable. Called by CompiledSchema::from_json so a schema whose scoping
cannot be honoured as declared never loads.
Scoped to the query the _entities path would actually consult — the first
returning the type with a sql_source — so this can never refuse a pair the
runtime would have ignored. Mutations are deliberately out of scope: entity
resolution merges no mutation’s declaration, so no mutation/type pair can
contradict one another in a way that changes what a read enforces.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn relationship_violations(&self) -> Vec<String>
pub fn relationship_violations(&self) -> Vec<String>
Relationships declared in a shape no embed can execute.
Returns one human-readable message per violation, empty when every relationship is
followable. Called from finish_load so a schema carrying an unexecutable
relationship never loads.
The join columns are resolved with the same two functions the REST executor uses —
Relationship::parent_join_column
and TypeDefinition::field_for_column
— so this cannot accept a schema the executor would fail to follow, nor refuse one
it would have handled.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn type_role_violations(&self) -> Vec<String>
pub fn type_role_violations(&self) -> Vec<String>
Declarations a role-gated type makes that the runtime cannot honour.
Returns one human-readable message per violation, empty when the schema is
enforceable. Called by CompiledSchema::from_json so a schema that would
enforce its own documentation only partially never loads.
Source§impl CompiledSchema
impl CompiledSchema
Sourcepub fn scope_violations(&self) -> Vec<String>
pub fn scope_violations(&self) -> Vec<String>
Fields that require a scope in a schema with no security section — no role is
defined, so no principal can hold the scope. One message per field, empty when the
schema is enforceable.