From 6424cb6464d7d8bef1b97715b58eacb7ce455dd0 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Fri, 20 Mar 2026 19:30:22 +0100 Subject: [PATCH 1/2] docs: integrate guards in typescript and rust guides Signed-off-by: David Dal Busco --- .../components/functions/query-vs-update.md | 5 ++ docs/guides/rust.mdx | 50 +++++++++++++++++++ docs/guides/typescript.mdx | 39 +++++++++++++-- 3 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 docs/guides/components/functions/query-vs-update.md diff --git a/docs/guides/components/functions/query-vs-update.md b/docs/guides/components/functions/query-vs-update.md new file mode 100644 index 00000000..eaa9fb78 --- /dev/null +++ b/docs/guides/components/functions/query-vs-update.md @@ -0,0 +1,5 @@ +### Query vs. Update + +A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information. + +An **update** is a function that can read and write state. Use it when your logic needs to persist data or trigger side effects. Updates can also be used for read operations when the response needs to be certified - making them suitable for security-sensitive use cases where data integrity must be guaranteed. diff --git a/docs/guides/rust.mdx b/docs/guides/rust.mdx index 3e5af06c..dfb7d866 100644 --- a/docs/guides/rust.mdx +++ b/docs/guides/rust.mdx @@ -105,6 +105,56 @@ Hooks execute asynchronously, separate from the request-response cycle. Changes --- +## Custom Functions + +Custom Functions let you define callable endpoints directly inside your Satellite. Unlike hooks, which react to events, custom functions are explicitly invoked - from your frontend or from other modules. + +import QueryVsUpdate from "./components/functions/query-vs-update.md"; + + + +### Defining a Function + +You define them using standard `ic_cdk` macros: + +```rust +use ic_cdk::query; + +#[ic_cdk::query] +fn hello_world() -> String { + "Hello, World!".to_string() +} + +include_satellite!(); +``` + +When you build your project, Juno automatically generates a client API based on your function definitions, so you can call them directly from your frontend. + +### Guards + +Guards let you protect custom functions by running a check before the handler executes. If the guard returns an error, the function is not invoked. + +```rust +use junobuild_satellite::caller_is_admin; + +fn my_function_guard() -> Result<(), String> { + caller_is_admin() +} + +#[ic_cdk::query(guard = "my_function_guard")] +fn hello_world() -> String { + "Hello, admin!".to_string() +} + +include_satellite!(); +``` + +Juno provides built-in guards you can use directly. + +📦 See all available built-in guards in the [SDK reference](#guards). + +--- + ## Assertions Assertions allow you to validate or reject operations before they are executed. They're useful for enforcing data integrity, security policies, or business rules inside your Satellite, and they run synchronously during the request lifecycle. diff --git a/docs/guides/typescript.mdx b/docs/guides/typescript.mdx index b93220c2..46b0387c 100644 --- a/docs/guides/typescript.mdx +++ b/docs/guides/typescript.mdx @@ -141,11 +141,9 @@ Custom Functions let you define callable endpoints directly inside your Satellit You define them using `defineQuery` or `defineUpdate`, describe their input and output shapes with the `j` type system, and Juno takes care of generating all the necessary bindings under the hood. -### Query vs. Update +import QueryVsUpdate from "./components/functions/query-vs-update.md"; -A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information. - -An **update** is a function that can read and write state. Use it when your logic needs to persist data or trigger side effects. Updates can also be used for read operations when the response needs to be certified - making them suitable for security-sensitive use cases where data integrity must be guaranteed. + ### Defining a Function @@ -182,6 +180,39 @@ import { functions } from "../declarations/satellite/satellite.api.ts"; await functions.helloWorld({ name: "World", id: Principal.anonymous() }); ``` +### Guards + +Guards let you protect custom functions by running a check before the handler executes. If the guard throws, the function is not invoked. + +```typescript +import { defineQuery } from "@junobuild/functions"; + +export const ping = defineQuery({ + guard: () => { + throw new Error("No pong today"); + }, + handler: () => { + console.log("Hello"); + } +}); +``` + +Juno also provides built-in guards you can use out of the box: + +```typescript +import { defineQuery } from "@junobuild/functions"; +import { callerIsAdmin } from "@junobuild/functions/sdk"; + +export const ping = defineQuery({ + guard: callerIsAdmin, + handler: () => { + console.log("Hello, admin!"); + } +}); +``` + +📦 See all available built-in guards in the [SDK reference](../reference/functions/typescript/sdk.mdx). + --- ## Assertions From afacab0fbec44f4e291d95ff5868d2eb65af543a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 18:32:10 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapshot?= =?UTF-8?q?=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index fc06c1e4..1c8cdcbd 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -7101,6 +7101,40 @@ Hooks execute asynchronously, separate from the request-response cycle. Changes --- +## Custom Functions + +Custom Functions let you define callable endpoints directly inside your Satellite. Unlike hooks, which react to events, custom functions are explicitly invoked - from your frontend or from other modules. + +### Query vs. Update + +A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information. + +An **update** is a function that can read and write state. Use it when your logic needs to persist data or trigger side effects. Updates can also be used for read operations when the response needs to be certified - making them suitable for security-sensitive use cases where data integrity must be guaranteed. + +### Defining a Function + +You define them using standard `ic_cdk` macros: + +``` +use ic_cdk::query;#[ic_cdk::query]fn hello_world() -> String { "Hello, World!".to_string()}include_satellite!(); +``` + +When you build your project, Juno automatically generates a client API based on your function definitions, so you can call them directly from your frontend. + +### Guards + +Guards let you protect custom functions by running a check before the handler executes. If the guard returns an error, the function is not invoked. + +``` +use junobuild_satellite::caller_is_admin;fn my_function_guard() -> Result<(), String> { caller_is_admin()}#[ic_cdk::query(guard = "my_function_guard")]fn hello_world() -> String { "Hello, admin!".to_string()}include_satellite!(); +``` + +Juno provides built-in guards you can use directly. + +📦 See all available built-in guards in the ([SDK reference](#guards)). + +--- + ## Assertions Assertions allow you to validate or reject operations before they are executed. They're useful for enforcing data integrity, security policies, or business rules inside your Satellite, and they run synchronously during the request lifecycle. @@ -7305,6 +7339,22 @@ When you build your project, a type-safe client API is automatically generated b import { functions } from "../declarations/satellite/satellite.api.ts";await functions.helloWorld({ name: "World", id: Principal.anonymous() }); ``` +### Guards + +Guards let you protect custom functions by running a check before the handler executes. If the guard throws, the function is not invoked. + +``` +import { defineQuery } from "@junobuild/functions";export const ping = defineQuery({ guard: () => { throw new Error("No pong today"); }, handler: () => { console.log("Hello"); }}); +``` + +Juno also provides built-in guards you can use out of the box: + +``` +import { defineQuery } from "@junobuild/functions";import { callerIsAdmin } from "@junobuild/functions/sdk";export const ping = defineQuery({ guard: callerIsAdmin, handler: () => { console.log("Hello, admin!"); }}); +``` + +📦 See all available built-in guards in the [SDK reference](/docs/reference/functions/typescript/sdk.md). + --- ## Assertions