Mutations
Use #[rpc_mutation] for write operations (create, update, delete). Unlike queries, mutations
are triggered explicitly via .mutate() — they don't auto-refetch.
#[rpc_mutation]
async fn create_order(input: OrderInput) -> Order {
db::insert_order(input).await
}// Direct call
const order = await rpc.mutate('create_order', orderInput);
// With options
const order = await rpc.mutate('create_order', orderInput, {
timeout: 10000,
});
// Void-input mutation
await rpc.mutate('reset');
// Result<T, E> — errors throw RpcError
try {
await rpc.mutate('delete_user', userId);
} catch (e) {
if (e instanceof RpcError) {
console.error(e.status, e.data);
}
}// Reactive wrapper — triggered explicitly via .mutate()
const order = createMutation(rpc, 'create_order', {
onSuccess: (data) => console.log('Created:', data),
onError: (err) => console.error(err),
});
// Fire-and-forget
order.mutate(orderInput);
// Await the result
const result = await order.mutateAsync(orderInput);
// Access state
// order.data — Order | undefined
// order.error — RpcError | undefined
// order.isLoading — boolean
// order.isSuccess — boolean
// order.isError — boolean
// order.reset() — clear stateNote: Input structs must derive both
Deserialize (for JSON parsing) and Serialize (so the CLI scanner can emit
TypeScript interfaces). Without Serialize, the struct won't appear in the generated
types.Void Input & Error Handling
Mutations can take no input (void) or return Result<T, E> for typed error handling. Errors are propagated as RpcError on the client side.
// Void-input mutation — no arguments needed
#[rpc_mutation]
async fn reset() -> bool {
cache::clear_all().await;
true
}
// Result error handling in mutations
#[rpc_mutation]
async fn delete_user(id: u64) -> Result<(), String> {
if !db::user_exists(id).await {
return Err("User not found".into());
}
db::delete_user(id).await;
Ok(())
}Per-Call Options
Every mutate() call accepts an optional trailing CallOptions object to override client-level defaults.
interface CallOptions {
headers?: Record<string, string>; // merged with client headers
timeout?: number; // override client timeout (ms)
signal?: AbortSignal; // combined with client signal
dedupe?: boolean; // per-call dedup override
}// Mutation with input + options
await rpc.mutate('create_order', orderInput, {
signal: abortController.signal,
dedupe: false,
});Try it
Echo — Struct Mutation
Send a message, optionally uppercase it. Demonstrates createMutation with struct input/output.