Component Interaction
The Blocklet SDK provides a comprehensive set of tools for Blocklets to interact with each other and with the Blocklet Server. This includes making API calls between components, retrieving detailed information about other components, monitoring their operational status, and subscribing to lifecycle events. Effective component interaction is crucial for building complex, distributed Blocklet applications.
For general information on Blocklet Server services, refer to the Core Services section. To understand how to handle notifications, see Notifications.
Making API Calls between Components#
The component.call
method enables your Blocklet to make authenticated API requests to other Blocklets or internal services running on the same Blocklet Server. This is the primary way for Blocklets to communicate with each other.
component.call(options, retryOptions)
#
Initiates an HTTP request to a target Blocklet or service.
Parameters
Name | Type | Description |
---|---|---|
|
| An object defining the request details. |
|
| Required. The name, title, or DID of the target component. |
|
| The HTTP method for the request (e.g., |
|
| Required. The API path relative to the target component's base URL. |
|
| The request body data for |
|
| Query parameters for the request. |
|
| Custom HTTP headers to include in the request. |
|
| Request timeout in milliseconds. |
|
| Optional. Configuration for retrying failed requests. |
|
| Number of retries before giving up. Defaults to |
|
| The exponential backoff factor. Defaults to |
|
| Randomize the retry delay. Defaults to |
|
| Minimum time between retries in milliseconds. Defaults to |
|
| Maximum time between retries in milliseconds. Defaults to |
|
| Callback function executed on each failed attempt. |
Returns
Name | Type | Description |
---|---|---|
|
| The Axios response object, containing the response data. If |
Example
import { component } from '@blocklet/sdk';
async function callAnotherComponentApi() {
try {
const response = await component.call({
name: 'my-other-blocklet-name', // Or DID: 'zNKj1hJzDkU1...', or title
method: 'GET',
path: '/api/data',
params: { limit: 10 },
});
console.log('Response from other component:', response.data);
} catch (error) {
console.error('Error calling component API:', error.message);
if (error.response) {
console.error('Status:', error.response.status);
console.error('Data:', error.response.data);
}
}
}
callAnotherComponentApi();
Example Response
{
"status": 200,
"data": {
"message": "Data from target component",
"items": [
"item1",
"item2"
]
}
}
This example demonstrates how to make a GET request to the /api/data
endpoint of a component named my-other-blocklet-name
, including a query parameter. The call
method automatically handles authentication and routing within the Blocklet Server environment.
Accessing Component Information#
The Blocklet SDK provides functions to retrieve details about installed components, their network endpoints, mount points, and associated resources.
component.getComponent(name: string)
#
Retrieves the detailed configuration and status of a specific component by its name, title, or DID.
Parameters
Name | Type | Description |
---|---|---|
|
| The name, title, or DID of the component. |
Returns
Name | Type | Description |
---|---|---|
|
| The component's mount point information, including its DID, name, status, mount point, and web endpoint. Returns |
MountPoint
Type Structure
Property | Type | Description |
---|---|---|
|
| The Decentralized Identifier of the component. |
|
| The programmatic name of the component. |
|
| The human-readable title of the component. |
|
| The current operational status of the component (e.g., |
|
| The URL path where the component is mounted on the Blocklet Server. |
|
| The internal port the component is listening on. |
|
| The internal web endpoint URL for the component. |
Example
import { component } from '@blocklet/sdk';
import { BlockletStatus } from '@blocklet/constant';
const myBlockletInfo = component.getComponent(process.env.BLOCKLET_COMPONENT_DID);
if (myBlockletInfo) {
console.log('Current Blocklet DID:', myBlockletInfo.did);
console.log('Current Blocklet Mount Point:', myBlockletInfo.mountPoint);
console.log('Current Blocklet Status:', BlockletStatus[myBlockletInfo.status]);
} else {
console.log('Could not find current Blocklet info.');
}
const otherBlockletInfo = component.getComponent('my-other-blocklet-name');
if (otherBlockletInfo) {
console.log('Other Blocklet Web Endpoint:', otherBlockletInfo.webEndpoint);
}
Example Response (for myBlockletInfo
)
{
"did": "zNKj1hJzDkU1...",
"name": "my-blocklet",
"title": "My Awesome Blocklet",
"status": 1,
"mountPoint": "/my-blocklet",
"port": 3000,
"webEndpoint": "http://127.0.0.1:3000"
}
component.getComponentWebEndpoint(keyword: string)
#
Retrieves the web endpoint URL for a specified component.
Parameters
Name | Type | Description |
---|---|---|
|
| The name, title, or DID of the component. |
Returns
Name | Type | Description |
---|---|---|
|
| The web endpoint URL of the component. Returns an empty string if the component or its endpoint is not found. |
Example
import { component } from '@blocklet/sdk';
const webEndpoint = component.getComponentWebEndpoint('my-other-blocklet-name');
console.log('Web Endpoint for my-other-blocklet-name:', webEndpoint);
Example Response
http://127.0.0.1:3001
component.getComponentMountPoint(keyword: string)
#
Retrieves the mount point path for a specified component.
Parameters
Name | Type | Description |
---|---|---|
|
| The name, title, or DID of the component. |
Returns
Name | Type | Description |
---|---|---|
|
| The mount point path of the component. Returns an empty string if the component is not found. |
Example
import { component } from '@blocklet/sdk';
const mountPoint = component.getComponentMountPoint('my-other-blocklet-name');
console.log('Mount Point for my-other-blocklet-name:', mountPoint);
Example Response
/my-other-blocklet
component.getResources(options)
#
Retrieves a list of resources exposed by components. This is useful for discovering shared assets or services from other Blocklets.
Parameters
Name | Type | Description |
---|---|---|
|
| Options for filtering resources. |
|
| Optional. Specifies which group of components to search: |
|
| Required. An array of objects specifying the resource DID and type to filter by. For example, |
|
| Optional. If |
Returns
Name | Type | Description |
---|---|---|
|
| An array of |
Resource
Type Structure
Property | Type | Description |
---|---|---|
|
| The title of the component exposing the resource. |
|
| The DID of the component exposing the resource. |
|
| The version of the component exposing the resource. |
|
| The status of the component exposing the resource. |
|
| The path to the resource (e.g., |
|
| Environment variables imported from the resource's public environment file. |
Example
import { component } from '@blocklet/sdk';
async function getSharedImages() {
const resources = await component.getResources({
scope: 'all',
types: [
{ did: 'z2D1...', type: 'image' }, // Replace with actual DID and resource type
],
});
console.log('Shared image resources:', resources);
}
getSharedImages();
Example Response
[
{
"title": "Image Blocklet",
"did": "z2D1...",
"version": "1.0.0",
"status": 1,
"path": "/z2D1.../image",
"env": {
"IMAGE_CDN_URL": "https://cdn.example.com/images"
}
}
]
component.getPackResources(options)
#
Retrieves resources specifically from components that are part of the current Blocklet's defined pack
group. This function is a convenience wrapper around getResources
with scope
set to 'pack'
and ignorePublic
set to true
.
Parameters
Name | Type | Description |
---|---|---|
|
| Options for filtering resources. |
|
| Required. An array of objects specifying the resource DID and type to filter by. For example, |
Returns
Name | Type | Description |
---|---|---|
|
| An array of |
Example
import { component } from '@blocklet/sdk';
async function getPackComponentPublicApis() {
const packResources = await component.getPackResources({
types: [
{ did: 'z2D2...', type: 'graphql-api' }, // Example DID and resource type for a pack component
],
});
console.log('Resources from pack components:', packResources);
}
getPackComponentPublicApis();
Example Response
[
{
"title": "GraphQL Service",
"did": "z2D2...",
"version": "0.5.0",
"status": 1,
"path": "/z2D2.../graphql-api",
"env": {}
}
]
Managing Component Status and Paths#
component.waitForComponentRunning(name: string, timeout?: number, interval?: number)
#
Waits for a specific component to reach a running state. This is useful for ensuring dependent components are fully operational before attempting to interact with them.
Parameters
Name | Type | Description |
---|---|---|
|
| The name, title, or DID of the component to wait for. |
|
| Optional. The maximum time to wait in milliseconds. Defaults to |
|
| Optional. The polling interval in milliseconds to check component status. Defaults to |
Returns
Name | Type | Description |
---|---|---|
|
| Resolves to |
Example
import { component } from '@blocklet/sdk';
async function ensureComponentIsReady() {
const componentName = 'my-database-blocklet';
try {
console.log(`Waiting for ${componentName} to start...`);
await component.waitForComponentRunning(componentName, 60000); // Wait up to 60 seconds
console.log(`${componentName} is now running.`);
// Proceed with operations that depend on this component
} catch (error) {
console.error(`Failed to wait for ${componentName} to run:`, error.message);
}
}
ensureComponentIsReady();
Example Response (on success)
Waiting for my-database-blocklet to start...
my-database-blocklet is now running.
component.getUrl(...parts: string[])
#
Constructs an absolute URL for paths within the current Blocklet or application, taking into account the Blocklet's mount point and the overall application URL.
Parameters
Name | Type | Description |
---|---|---|
|
| Path segments to join and append to the base URL. |
Returns
Name | Type | Description |
---|---|---|
|
| The fully qualified URL. |
Example
import { component } from '@blocklet/sdk';
async function generateAbsoluteUrls() {
// Assuming current Blocklet is mounted at /my-app and appUrl is http://localhost:8080
const apiUrl = component.getUrl('api', 'v1', 'users');
console.log('API URL:', apiUrl);
const homepageUrl = component.getUrl(); // Gets the base URL of the current Blocklet
console.log('Homepage URL:', homepageUrl);
}
generateAbsoluteUrls();
Example Response
API URL: http://localhost:8080/my-app/api/v1/users
Homepage URL: http://localhost:8080/my-app
component.getRelativeUrl(...parts: string[])
#
Constructs a URL relative to the current Blocklet's mount point. This is useful for internal routing or client-side paths.
Parameters
Name | Type | Description |
---|---|---|
|
| Path segments to join and append to the relative base URL. |
Returns
Name | Type | Description |
---|---|---|
|
| The relative URL. |
Example
import { component } from '@blocklet/sdk';
async function generateRelativeUrls() {
// Assuming current Blocklet is mounted at /my-app
const relativeApiPath = component.getRelativeUrl('data', 'items');
console.log('Relative API Path:', relativeApiPath);
const relativeRoot = component.getRelativeUrl(); // Gets the mount point itself
console.log('Relative Root:', relativeRoot);
}
generateRelativeUrls();
Example Response
Relative API Path: /my-app/data/items
Relative Root: /my-app
component.getResourceExportDir({ projectId, releaseId }: { projectId: string; releaseId?: string })
#
Gets the file system directory path where exported resources for a specific project and optionally a release are stored within the Blocklet Server's data directory.
Parameters
Name | Type | Description |
---|---|---|
|
| Required. The ID of the project. |
|
| Optional. The ID of the specific release within the project. |
Returns
Name | Type | Description |
---|---|---|
|
| The absolute file system path to the resource export directory. |
Example
import { component } from '@blocklet/sdk';
async function getResourceStoragePath() {
const projectId = 'my-project-id-123';
const releaseId = 'my-release-id-abc';
const resourceDir = component.getResourceExportDir({ projectId });
console.log('Project Resource Directory:', resourceDir);
const releaseResourceDir = component.getResourceExportDir({ projectId, releaseId });
console.log('Release Resource Directory:', releaseResourceDir);
}
getResourceStoragePath();
Example Response
Project Resource Directory: /var/lib/blocklet/data/projects/my-project-id-123/resources
Release Resource Directory: /var/lib/blocklet/data/projects/my-project-id-123/releases/my-release-id-abc/resources
component.getReleaseExportDir({ projectId, releaseId }: { projectId: string; releaseId?: string })
#
Gets the file system directory path where exported releases for a specific project are stored within the Blocklet Server's data directory.
Parameters
Name | Type | Description |
---|---|---|
|
| Required. The ID of the project. |
|
| Optional. The ID of the specific release within the project. |
Returns
Name | Type | Description |
---|---|---|
|
| The absolute file system path to the release export directory. |
Example
import { component } from '@blocklet/sdk';
async function getReleaseStoragePath() {
const projectId = 'my-project-id-123';
const releaseId = 'my-release-id-abc';
const projectReleaseDir = component.getReleaseExportDir({ projectId });
console.log('Project Release Directory:', projectReleaseDir);
const specificReleaseDir = component.getReleaseExportDir({ projectId, releaseId });
console.log('Specific Release Directory:', specificReleaseDir);
}
getReleaseStoragePath();
Example Response
Project Release Directory: /var/lib/blocklet/data/projects/my-project-id-123
Specific Release Directory: /var/lib/blocklet/data/projects/my-project-id-123/releases/my-release-id-abc
Component Lifecycle Events#
The Blocklet SDK provides an events
emitter that allows your Blocklet to subscribe to various lifecycle events related to components on the Blocklet Server. This enables reactive behavior within your application based on changes in other components' status.
Available Events
The component.events.Events
object defines the names of the events you can subscribe to:
Event Name | Description |
---|---|
| Emitted when a new component is installed. |
| Emitted when a component's metadata or configuration is updated. |
| Emitted when a component transitions to a running state. |
| Emitted when a component transitions to a stopped state. |
| Emitted when a component is uninstalled. |
| Emitted when the application's environment variables or preferences are updated. |
Example
import { component } from '@blocklet/sdk';
import { BlockletStatus } from '@blocklet/constant';
// Subscribe to component started event
component.events.on(component.events.Events.componentStarted, (components) => {
console.log('One or more components have started:');
components.forEach(comp => {
console.log(`- ${comp.title} (DID: ${comp.did}) is now ${BlockletStatus[comp.status]}`);
});
});
// Subscribe to component removed event
component.events.on(component.events.Events.componentRemoved, (components) => {
console.log('One or more components have been removed:');
components.forEach(comp => {
console.log(`- ${comp.title} (DID: ${comp.did}) has been removed`);
});
});
// Subscribe to environment update event
component.events.on(component.events.Events.envUpdate, (updatedEnv) => {
console.log('Application environment updated:', updatedEnv);
});
console.log('Blocklet is listening for component lifecycle events...');
This example demonstrates how to listen for various component lifecycle events using the component.events
emitter. The callback functions will be triggered whenever the respective events occur on the Blocklet Server, providing a list of affected components or updated environment variables.
This section covered how Blocklets can interact with each other and the Blocklet Server, from making API calls to monitoring lifecycle events. This capability is fundamental for building modular and dynamic decentralized applications. Next, explore the Middleware Reference to understand how to leverage built-in Express.js middleware for common web functionalities.