Skip to content

Commit 00a3f56

Browse files
docs: integrate guards in typescript and rust guides (#676)
* docs: integrate guards in typescript and rust guides Signed-off-by: David Dal Busco <david.dalbusco@outlook.com> * 📄 Update LLMs.txt snapshot for PR review --------- Signed-off-by: David Dal Busco <david.dalbusco@outlook.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent aa939ce commit 00a3f56

4 files changed

Lines changed: 140 additions & 4 deletions

File tree

.llms-snapshots/llms-full.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7101,6 +7101,40 @@ Hooks execute asynchronously, separate from the request-response cycle. Changes
71017101

71027102
---
71037103

7104+
## Custom Functions
7105+
7106+
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.
7107+
7108+
### Query vs. Update
7109+
7110+
A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information.
7111+
7112+
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.
7113+
7114+
### Defining a Function
7115+
7116+
You define them using standard `ic_cdk` macros:
7117+
7118+
```
7119+
use ic_cdk::query;#[ic_cdk::query]fn hello_world() -> String { "Hello, World!".to_string()}include_satellite!();
7120+
```
7121+
7122+
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.
7123+
7124+
### Guards
7125+
7126+
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.
7127+
7128+
```
7129+
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!();
7130+
```
7131+
7132+
Juno provides built-in guards you can use directly.
7133+
7134+
📦 See all available built-in guards in the ([SDK reference](#guards)).
7135+
7136+
---
7137+
71047138
## Assertions
71057139

71067140
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
73057339
import { functions } from "../declarations/satellite/satellite.api.ts";await functions.helloWorld({ name: "World", id: Principal.anonymous() });
73067340
```
73077341

7342+
### Guards
7343+
7344+
Guards let you protect custom functions by running a check before the handler executes. If the guard throws, the function is not invoked.
7345+
7346+
```
7347+
import { defineQuery } from "@junobuild/functions";export const ping = defineQuery({ guard: () => { throw new Error("No pong today"); }, handler: () => { console.log("Hello"); }});
7348+
```
7349+
7350+
Juno also provides built-in guards you can use out of the box:
7351+
7352+
```
7353+
import { defineQuery } from "@junobuild/functions";import { callerIsAdmin } from "@junobuild/functions/sdk";export const ping = defineQuery({ guard: callerIsAdmin, handler: () => { console.log("Hello, admin!"); }});
7354+
```
7355+
7356+
📦 See all available built-in guards in the [SDK reference](/docs/reference/functions/typescript/sdk.md).
7357+
73087358
---
73097359

73107360
## Assertions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
### Query vs. Update
2+
3+
A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information.
4+
5+
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.

docs/guides/rust.mdx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,56 @@ Hooks execute asynchronously, separate from the request-response cycle. Changes
105105

106106
---
107107

108+
## Custom Functions
109+
110+
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.
111+
112+
import QueryVsUpdate from "./components/functions/query-vs-update.md";
113+
114+
<QueryVsUpdate />
115+
116+
### Defining a Function
117+
118+
You define them using standard `ic_cdk` macros:
119+
120+
```rust
121+
use ic_cdk::query;
122+
123+
#[ic_cdk::query]
124+
fn hello_world() -> String {
125+
"Hello, World!".to_string()
126+
}
127+
128+
include_satellite!();
129+
```
130+
131+
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.
132+
133+
### Guards
134+
135+
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.
136+
137+
```rust
138+
use junobuild_satellite::caller_is_admin;
139+
140+
fn my_function_guard() -> Result<(), String> {
141+
caller_is_admin()
142+
}
143+
144+
#[ic_cdk::query(guard = "my_function_guard")]
145+
fn hello_world() -> String {
146+
"Hello, admin!".to_string()
147+
}
148+
149+
include_satellite!();
150+
```
151+
152+
Juno provides built-in guards you can use directly.
153+
154+
📦 See all available built-in guards in the [SDK reference](#guards).
155+
156+
---
157+
108158
## Assertions
109159

110160
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.

docs/guides/typescript.mdx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,9 @@ Custom Functions let you define callable endpoints directly inside your Satellit
141141

142142
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.
143143

144-
### Query vs. Update
144+
import QueryVsUpdate from "./components/functions/query-vs-update.md";
145145

146-
A **query** is a read-only function. It returns data without modifying any state. Queries are fast and suitable for fetching or computing information.
147-
148-
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.
146+
<QueryVsUpdate />
149147

150148
### Defining a Function
151149

@@ -182,6 +180,39 @@ import { functions } from "../declarations/satellite/satellite.api.ts";
182180
await functions.helloWorld({ name: "World", id: Principal.anonymous() });
183181
```
184182

183+
### Guards
184+
185+
Guards let you protect custom functions by running a check before the handler executes. If the guard throws, the function is not invoked.
186+
187+
```typescript
188+
import { defineQuery } from "@junobuild/functions";
189+
190+
export const ping = defineQuery({
191+
guard: () => {
192+
throw new Error("No pong today");
193+
},
194+
handler: () => {
195+
console.log("Hello");
196+
}
197+
});
198+
```
199+
200+
Juno also provides built-in guards you can use out of the box:
201+
202+
```typescript
203+
import { defineQuery } from "@junobuild/functions";
204+
import { callerIsAdmin } from "@junobuild/functions/sdk";
205+
206+
export const ping = defineQuery({
207+
guard: callerIsAdmin,
208+
handler: () => {
209+
console.log("Hello, admin!");
210+
}
211+
});
212+
```
213+
214+
📦 See all available built-in guards in the [SDK reference](../reference/functions/typescript/sdk.mdx).
215+
185216
---
186217

187218
## Assertions

0 commit comments

Comments
 (0)