Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .llms-snapshots/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions docs/guides/components/functions/query-vs-update.md
Original file line number Diff line number Diff line change
@@ -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.
50 changes: 50 additions & 0 deletions docs/guides/rust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

<QueryVsUpdate />

### 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.
Expand Down
39 changes: 35 additions & 4 deletions docs/guides/typescript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
<QueryVsUpdate />

### Defining a Function

Expand Down Expand Up @@ -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
Expand Down