Skip to main content

Development

When you're ready to implement Functions within your Juno Satellite, you'll have a variety of event-driven macros at your disposal, enabling custom logic execution in response to specific actions. Here's how to implement each available Function:


Event-driven Functions​

Event-driven functions respond to actions occurring in your Satellite. They are triggered automatically and never invoked directly.


Hooks​

Hooks allow you to define event-driven logic that responds to specific actions within your Satellite. The following is a list of available hooks and their respective use cases.

on_set_doc​

Triggered when a document is created or updated in the datastore.

#[on_set_doc]
async fn on_set_doc(context: OnSetDocContext) -> Result<(), String> {
// Custom logic for handling document creation or updates
Ok(())
}

on_set_many_docs​

Invoked for batch operations involving multiple document creations or updates.

#[on_set_many_docs]
async fn on_set_many_docs(context: OnSetManyDocsContext) -> Result<(), String> {
// Custom logic for handling multiple document creations or updates
Ok(())
}

on_delete_doc​

Invoked when a document is deleted from the datastore.

#[on_delete_doc]
async fn on_delete_doc(context: OnDeleteDocContext) -> Result<(), String> {
// Custom logic for handling document deletion
Ok(())
}

on_delete_many_docs​

Used when multiple documents are deleted in a batch operation.

#[on_delete_many_docs]
async fn on_delete_many_docs(context: OnDeleteManyDocsContext) -> Result<(), String> {
// Custom logic for handling the deletion of multiple documents
Ok(())
}

on_delete_filtered_docs​

Invoked when documents are deleted according to specified filters in the datastore.

#[on_delete_filtered_docs]
async fn on_delete_filtered_docs(context: OnDeleteFilteredDocsContext) -> Result<(), String> {
// Custom logic for handling the deletion of filtered documents
Ok(())
}

on_upload_asset​

Triggered during the process of uploading an asset.

#[on_upload_asset]
async fn on_upload_asset(context: OnUploadAssetContext) -> Result<(), String> {
// Custom logic for handling asset uploads
Ok(())
}

on_delete_asset​

Activated when an asset is removed from the datastore.

#[on_delete_asset]
async fn on_delete_asset(context: OnDeleteAssetContext) -> Result<(), String> {
// Custom logic for handling asset deletion
Ok(())
}

on_delete_many_assets​

Used for operations that involve deleting multiple assets in a batch.

#[on_delete_many_assets]
async fn on_delete_many_assets(context: OnDeleteManyAssetsContext) -> Result<(), String> {
// Custom logic for handling the deletion of multiple assets
Ok(())
}

on_delete_filtered_assets​

Invoked when assets are deleted according to specified filters in the storage.

#[on_delete_filtered_assets]
async fn on_delete_filtered_assets(context: OnDeleteFilteredAssetsContext) -> Result<(), String> {
// Custom logic for handling the deletion of filtered assets
Ok(())
}

on_init​

Called during the initialization of the Satellite. This hook is invoked when the Satellite is first deployed and can be used to set up initial configurations or resources.

#[on_init]
fn on_init() -> Result<(), String> {
// Custom logic for initialization
Ok(())
}

Unlike datastore or storage hooks, on_init cannot be scoped to specific collections or assets, as it is meant to handle global initialization logic.

This feature is not enabled by default. To use it, you’ll need to opt in by updating your Cargo.toml file.

[dependencies]
junobuild-satellite = { version = "*", features = ["default", "on_init"] }

on_post_upgrade​

Invoked after the Satellite has been upgraded to a new version. This hook is typically used to manage migration tasks, or starting custom processes like timers.

#[on_post_upgrade]
fn on_post_upgrade() -> Result<(), String> {
// Custom logic for post-upgrade tasks
Ok(())
}

Similar to on_init, the on_post_upgrade hook cannot be scoped to collections or assets. It operates globally to handle upgrade-related operations.

This feature is not enabled by default. To use it, you’ll need to opt in by updating your Cargo.toml file.

[dependencies]
junobuild-satellite = { version = "*", features = ["default", "on_post_upgrade"] }

Assertions​

Assertions enable validation checks before specific actions are executed within your Satellite. The following is a list of available assertions and their functionalities.

assert_set_doc​

Ensures a document can be created or updated.

#[assert_set_doc]
fn assert_set_doc(_context: AssertSetDocContext) -> Result<(), String> {
// Custom logic for asserting a document's creation or update is possible
// Return an error if the condition fails to prevent the action
Ok(())
}

assert_delete_doc​

Verifies that a document can be deleted.

#[assert_delete_doc]
fn assert_delete_doc(context: AssertDeleteDocContext) -> Result<(), String> {
// Custom logic for asserting a document can be deleted
// Return an error if the condition fails to prevent the action
Ok(())
}

assert_upload_asset​

Confirms an asset upload can be committed.

#[assert_upload_asset]
fn assert_upload_asset(_context: AssertUploadAssetContext) -> Result<(), String> {
// Custom logic for asserting an asset upload is possible
// Return an error if the condition fails to prevent the action
Ok(())
}

assert_delete_asset​

Checks that an asset can be deleted.

#[assert_delete_asset]
fn assert_delete_asset(_context: AssertDeleteAssetContext) -> Result<(), String> {
// Custom logic for asserting an asset can be deleted
// Return an error if the condition fails to prevent the action
Ok(())
}

When Hooks and Assertions Run​

When no attributes are provided, the hook is triggered for any document set in any collection. For better control and performance, it’s recommended to scope the hook to a specific list of collections.

This behavior applies to all hooks and assertions, except for the lifecycle hooks such as on_init or on_post_upgrade, which operate globally.

#[on_set_doc(collections = ["demo"])]
async fn on_set_doc(context: OnSetDocContext) -> Result<(), String> {
// Custom logic for handling document creation or updates
Ok(())
}

The attributes accept a list of comma-separated collections. If the attribute array is left empty, the hook will never be called.


Callable Functions​

Callable functions (also referenced as custom functions) are explicitly invoked — from your frontend or from other canisters.

Query​

Defines a read-only function that returns data without modifying any state.

#[ic_cdk::query]
fn my_function() -> String {
// Your logic here
}

Update​

Defines a function that can read and write state.

#[ic_cdk::update]
fn my_function() -> String {
// Your logic here
}

Further Resources​

For practical use cases, check out the Examples page with sample projects and resources available on GitHub.