pub struct MutationDefinition {Show 18 fields
pub name: String,
pub return_type: String,
pub arguments: Vec<ArgumentDefinition>,
pub description: Option<String>,
pub operation: MutationOperation,
pub deprecation: Option<DeprecationInfo>,
pub sql_source: Option<String>,
pub inject_params: IndexMap<String, InjectedParamSource>,
pub invalidates_fact_tables: Vec<String>,
pub invalidates_views: Vec<String>,
pub rest_path: Option<String>,
pub rest_method: Option<String>,
pub upsert_function: Option<String>,
pub requires_role: Option<String>,
pub changelog: bool,
pub input_style: InputStyle,
pub changelog_pre_image: bool,
pub cascade: bool,
}Expand description
A mutation definition compiled from @fraiseql.mutation.
Mutations are declarative bindings to database functions. They describe which function to call, not arbitrary logic.
§Example
use fraiseql_core::schema::{MutationDefinition, MutationOperation};
let mutation = MutationDefinition::new("createUser", "User");Fields§
§name: StringMutation name (e.g., “createUser”).
return_type: StringReturn type name.
arguments: Vec<ArgumentDefinition>Input arguments.
description: Option<String>Description.
operation: MutationOperationSQL operation type.
deprecation: Option<DeprecationInfo>Deprecation information (from @deprecated directive). When set, this mutation is marked as deprecated in the schema.
sql_source: Option<String>PostgreSQL function name to call for this mutation.
When set, the runtime calls SELECT * FROM {sql_source}($1, $2, ...) with the
mutation arguments in ArgumentDefinition order, and parses the result as an
app.mutation_response composite row.
inject_params: IndexMap<String, InjectedParamSource>Server-side parameters injected from JWT claims at runtime.
Keys are SQL parameter names. Values describe where to source the runtime value. These params are NOT exposed as GraphQL arguments.
For mutations: injected params are appended to the positional function call args after client-provided arguments, in map insertion order. The SQL function signature must declare the injected parameters last.
Works on PostgreSQL, SQL Server, and MySQL. SQLite has no stored-routine mechanism and will return an error if inject is configured on a mutation.
invalidates_fact_tables: Vec<String>Fact tables whose version counter should be bumped after this mutation succeeds.
When the mutation PostgreSQL function returns successfully, the runtime calls
SELECT bump_tf_version($1) for each listed table, incrementing the version used
in fact-table cache keys. This ensures that analytic/aggregate queries backed by
FactTableVersionStrategy::VersionTable are automatically invalidated.
Each entry must be a valid SQL identifier validated at compile time.
§Example
@fraiseql.mutation(
sql_source="fn_create_order",
invalidates_fact_tables=["tf_sales", "tf_order_count"],
)
def create_order(amount: Decimal) -> Order: ...invalidates_views: Vec<String>View names whose cached query results should be invalidated after this mutation succeeds.
When the CachedDatabaseAdapter is active, the runtime calls
invalidate_views() with these names, clearing all cache entries that
read from the specified views.
If empty and the mutation return type has a sql_source, the runtime
infers the primary view from the return type.
Each entry must be a valid SQL identifier validated at compile time.
rest_path: Option<String>Custom REST path override (e.g., "/users/{id}").
rest_method: Option<String>REST HTTP method override (e.g., "POST", "PUT", "PATCH").
upsert_function: Option<String>PostgreSQL upsert function name for PUT semantics (insert-or-update).
requires_role: Option<String>Role required to execute this mutation and see it in introspection.
When set, only users whose SecurityContext.roles contains this role can
discover and execute the mutation. Others receive "Unknown mutation"
(not FORBIDDEN) to prevent role enumeration — mirroring
QueryDefinition::requires_role.
changelog: boolWhether a successful run of this mutation writes a Change-Spine change-log
row (default true).
Composes as a logical AND with the global
RuntimeConfig.changelog_enabled: a row
is written only when the global switch is on and this flag is true.
Set false to opt a single mutation out of the in-transaction outbox
write — e.g. a hot endpoint that need not appear in the Change Spine —
while leaving the rest of the schema logging. Serde-defaults to true, so
a compiled schema produced before this field existed keeps logging.
input_style: InputStyleHow the GraphQL input argument is passed to the SQL function:
Flatten (positional columns, the default) or
Jsonb (the whole input as one jsonb arg).
Orthogonal to operation: jsonb forces the
single-JSONB-argument path regardless of the DML verb, so an
Insert/Delete/Custom mutation backed by a single-jsonb-wrapper
function (fn(input_payload jsonb, …)) keeps its real verb — and the
Change Spine records the true modification_type — while still
receiving the whole input as one argument. Update mutations always
take the single-JSONB path whatever this is set to.
Defaults to flatten; an absent value is byte-identical to the
behavior before this field existed (so it adds no compiled-schema bytes
and does not churn the codegen schema hash).
changelog_pre_image: boolWhether a successful, state-changing run of this mutation also records the
changed entity’s pre-image (before-state) into the Change-Spine
object_data_before column, alongside the after-image it already writes to
object_data. Default false.
The pre-image is sourced from an optional entity_before on the mutation’s
app.mutation_response (the same way the after-image is sourced from
entity); the outbox CTE reads r.entity_before only when this is set,
so an opted-in mutation’s response type must expose that column.
Opt-in per mutation so the audit cost (extra storage + a backend that
computes the pre-mutation snapshot) is paid only by the audit-sensitive
mutations that need an inline Debezium-style {before, after} on the single
event — most consumers react to the after-state, and an update’s
before-state is the previous row’s after-state, reconstructable from the
seq-ordered stream.
Defaults to false; an absent value is byte-identical to the behavior
before this field existed (so it adds no compiled-schema bytes and does not
churn the codegen schema hash).
cascade: boolWhether this mutation exposes and enforces the typed graphql-cascade
cascade field on its success payload. Default false.
When true, the runtime surfaces a typed, selection-gated cascade
field — mutation responses carrying all affected entities, per the
graphql-cascade spec — whose entities are projected to camelCase and run
through the field-level authorizer (#423), exactly like a queried
entity. When false, no cascade surface exists and any cascade the SQL
function returns is ignored.
Set via the authoring SDK’s @fraiseql.type(crud=True, cascade=True) (or
@fraiseql.mutation(cascade=True)); before this field existed the
compiler silently dropped that flag.
Defaults to false; an absent value is byte-identical to the behavior
before this field existed (so it adds no compiled-schema bytes and does
not churn the codegen schema hash).
Implementations§
Source§impl MutationDefinition
impl MutationDefinition
Sourcepub fn new(name: impl Into<String>, return_type: impl Into<String>) -> Self
pub fn new(name: impl Into<String>, return_type: impl Into<String>) -> Self
Create a new mutation definition.
Sourcepub fn deprecated(self, reason: Option<String>) -> Self
pub fn deprecated(self, reason: Option<String>) -> Self
Mark this mutation as deprecated.
§Example
use fraiseql_core::schema::MutationDefinition;
let mutation = MutationDefinition::new("oldCreateUser", "User")
.deprecated(Some("Use 'createUser' instead".to_string()));
assert!(mutation.is_deprecated());Sourcepub const fn is_deprecated(&self) -> bool
pub const fn is_deprecated(&self) -> bool
Check if this mutation is deprecated.
Sourcepub fn deprecation_reason(&self) -> Option<&str>
pub fn deprecation_reason(&self) -> Option<&str>
Get the deprecation reason if deprecated.
Trait Implementations§
Source§impl Clone for MutationDefinition
impl Clone for MutationDefinition
Source§fn clone(&self) -> MutationDefinition
fn clone(&self) -> MutationDefinition
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more