组件间通信
在一个由多个组件组成的 Blocklet 应用中,使它们能够安全可靠地相互通信至关重要。Blocklet SDK 提供了一个高级实用工具 component.call,专为此目的而设计。该方法通过处理服务发现、请求签名和自动重试,简化了组件间的 API 调用。
这种方法比直接发起 HTTP 请求更健壮,因为它抽象了底层环境的复杂性,例如动态端口和 Docker 网络,同时确保所有通信都经过身份验证。
发起安全 API 调用#
组件间通信的主要方法是 component.call。它作为 HTTP 客户端(axios)的包装器,但会自动注入必要的身份验证标头,以验证调用组件的身份。
基本用法#
这是一个基本示例,演示一个组件如何调用名为“user-service”的另一个组件上的 API 端点。
Calling another component
import component from '@blocklet/sdk/component';
async function getUserProfile(userId) {
try {
const response = await component.call({
name: 'user-service', // 目标组件的名称、DID 或标题
method: 'GET',
path: `/api/users/${userId}`,
});
console.log('用户个人资料:', response.data);
return response.data;
} catch (error) {
console.error('调用 user-service 失败:', error.message);
}
}工作原理#
component.call 函数通过几个关键步骤简化了通信过程:
- 服务发现:它在应用程序的组件注册表中查找目标组件(例如,“user-service”),以找到其当前位置和元数据。
- 端点解析:它构造正确的内部 URL 以访问该组件,自动处理 Docker 容器网络等复杂性。
- 请求签名:在发送请求之前,它会自动添加特殊的
x-component-*标头。这些标头包含使用调用组件的密钥生成的签名,以证明其身份。 - API 调用:它使用配置的方法、路径和数据执行 HTTP 请求。
- 自动重试:如果请求因暂时的服务器错误(例如,5xx 状态码)而失败,它将自动以递增的延迟(指数退避)重试几次请求。
此流程确保通信既可靠又安全。接收组件可以使用 session 中间件 来验证签名并授权请求。

call 参数#
component.call 函数接受一个包含以下属性的选项对象:
请求体,通常与 POST、PUT 或 PATCH 方法一起使用。
返回值#
该函数返回一个 Promise,它会解析为一个 AxiosResponse 对象,其中包含 data、status 和 headers 等属性。
高级用法#
自定义重试行为#
你可以通过向 component.call 传递第二个参数来自定义自动重试逻辑。这对于适应端点的特定可靠性需求非常有用。
Custom Retry Options
import component from '@blocklet/sdk/component';
const callOptions = {
name: 'data-processor',
method: 'POST',
path: '/api/process',
data: { job: 'some-long-job' },
};
const retryOptions = {
retries: 5, // 总共尝试 5 次
minTimeout: 1000, // 两次重试之间至少等待 1 秒
factor: 2, // 每次失败后等待时间加倍
};
async function processData() {
const response = await component.call(callOptions, retryOptions);
return response.data;
}retryOptions 对象可以具有以下属性:
处理流式响应#
对于返回流的端点(例如,下载大文件),你可以设置 responseType: 'stream'。这允许你在数据到达时进行处理,而无需将整个响应缓冲在内存中。
Streaming a File
import fs from 'fs';
import component from '@blocklet/sdk/component';
async function downloadBackup() {
const response = await component.call({
name: 'backup-service',
method: 'GET',
path: '/api/export',
responseType: 'stream',
});
const writer = fs.createWriteStream('backup.zip');
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});
}通过使用 component.call,你可以轻松构建健壮且安全的多组件应用程序。接下来,你需要学习如何通过验证这些传入的调用来保护你的组件的 API 端点。详情请参阅 Session 中间件 指南。