@be-link/volcengine-openapi-sdk
v0.0.2
Published
Volcengine Node.js SDK (TypeScript), simplified port of volc-sdk-java core features.
Readme
Volcengine Node.js SDK(TypeScript 简化版)
说明:这是基于 volc-sdk-java 的核心认证与请求流程,使用 Node.js + TypeScript 实现的一个简化版 SDK,主要包含:
- 签名算法:对齐 Java 版的 V4 签名(
HMAC-SHA256,X-Date、X-Content-Sha256、Authorization等头) - HTTP 调用:基于 Node 原生
http/https模块 - 通用客户端:通过传入
region、service、host等信息发起任意 API 请求
安装与构建
在仓库根目录:
cd volcengine-openapi-sdk-node
npm install
npm run build基本使用示例
import { VolcClient } from '@be-link/volcengine-openapi-sdk-node';
async function main() {
const client = new VolcClient({
region: 'cn-north-1',
service: 'iam', // 与 Java 版 Credentials.service 对齐
host: 'open.volcengineapi.com',
scheme: 'https',
});
const resp = await client.request({
method: 'GET',
path: '/',
query: {
Action: 'ListUsers',
Version: '2018-01-01',
},
});
console.log(resp.statusCode, resp.body.toString('utf8'));
}
main().catch(console.error);鉴权与凭证加载
- 环境变量:
VOLC_ACCESSKEY:Access KeyVOLC_SECRETKEY:Secret Key
- 配置文件(可选,对齐 Java 版行为):
- 路径:
~/.volc/config - 内容示例:
- 路径:
{
"ak": "your_ak",
"sk": "your_sk",
"service": "iam",
"region": "cn-north-1"
}如果构造 VolcClient 时没有显式传入 accessKeyId / secretAccessKey,SDK 会依次尝试:
- 环境变量
VOLC_ACCESSKEY/VOLC_SECRETKEY ~/.volc/config文件
生成预签名 URL
const url = client.getSignedUrl({
method: 'GET',
path: '/',
query: {
Action: 'ListUsers',
Version: '2018-01-01',
},
});
console.log('signed url:', url);使用模块化 API
SDK 提供了模块化的 API 封装,使用起来更加便捷:
import { VolClient, LiveStreamRoomModule } from '@be-link/volcengine-openapi-sdk-node';
const client = new VolClient({
region: 'cn-beijing',
service: 'livesaas',
host: 'livesaas.volcengineapi.com',
});
// 创建模块实例
const liveStreamRoom = new LiveStreamRoomModule(client);
// 调用 API
const response = await liveStreamRoom.listActivityAPI({
PageNo: 1,
PageItemCount: 10,
});添加新模块 API
SDK 采用模块化设计,每个业务模块在 src/module/ 目录下拥有独立的文件夹。以下说明如何添加一个新的业务模块。
步骤 1:创建模块目录结构
在 src/module/ 目录下创建新模块的文件夹,例如 myModule:
src/module/myModule/
├── types.ts # 类型定义和接口
├── api.ts # API 方法实现
├── code.ts # 错误码映射(可选)
└── index.ts # 模块导出步骤 2:定义类型和接口(types.ts)
在 types.ts 中定义请求参数、响应类型和模块接口:
import { VolEngineResponse, IRateLimiter, RetryConfig, TimeoutConfig } from '../../types';
// 请求参数类型
export interface MyAPIRequest {
/** 参数说明 */
param1?: string;
param2?: number;
}
// 响应结果类型
export interface MyAPIResult {
/** 结果字段说明 */
data?: any;
}
// 响应类型
export type MyAPIResponse = VolEngineResponse<MyAPIResult>;
// 模块接口:定义所有 API 方法签名
export interface IMyModuleAPI {
/**
* API 方法说明
*/
myAPI(
params: MyAPIRequest,
rateLimiter?: IRateLimiter,
retryConfig?: RetryConfig,
timeoutConfig?: TimeoutConfig
): Promise<MyAPIResponse>;
}步骤 3:实现 API 方法(api.ts)
在 api.ts 中实现接口定义的方法:
import { IClient } from '../../baseClient';
import { IRateLimiter, RetryConfig, TimeoutConfig } from '../../types';
import {
IMyModuleAPI,
MyAPIRequest,
MyAPIResponse,
} from './types';
import { myModuleErrorCodeMapper } from './code'; // 如果有错误码映射
export class MyModule implements IMyModuleAPI {
constructor(private readonly client: IClient) {}
async myAPI(
params: MyAPIRequest,
rateLimiter?: IRateLimiter,
retryConfig?: RetryConfig,
timeoutConfig?: TimeoutConfig
): Promise<MyAPIResponse> {
const response = await this.client.request({
method: 'POST', // 或 'GET'
path: '/',
query: {
Action: 'MyAPI', // API 名称
Version: '2024-01-01', // API 版本
},
body: params,
rateLimiter,
retryConfig,
timeoutConfig,
errorCodeMapper: myModuleErrorCodeMapper, // 可选:错误码映射器
});
// 解析响应体
const bodyStr = response.body.toString('utf8');
return JSON.parse(bodyStr);
}
}步骤 4:定义错误码映射(code.ts,可选)
如果需要自定义错误码的中文描述,创建 code.ts:
import { IErrorCodeMapper } from '../../types';
// 错误码映射表
export const ErrorCodeMap: Record<string, string> = {
'InvalidParameter.Param1Invalid': '参数 param1 无效。请修改后重试。',
'InternalError.InternalReqFailed': '由于未知错误,请求失败。请联系技术支持获取帮助。',
};
// 获取错误信息的辅助函数
export function getErrorMessage(errorCode?: string): string | undefined {
if (!errorCode) {
return undefined;
}
// 精确匹配
if (ErrorCodeMap[errorCode]) {
return ErrorCodeMap[errorCode];
}
// 通配符匹配(例如:InvalidParameter.%sInvalid)
for (const [pattern, message] of Object.entries(ErrorCodeMap)) {
if (pattern.includes('%s')) {
const regexPattern = pattern.replace(/%s/g, '.*');
const regex = new RegExp(`^${regexPattern}$`);
if (regex.test(errorCode)) {
return message;
}
}
}
return undefined;
}
// 错误码映射器类
export class MyModuleErrorCodeMapper implements IErrorCodeMapper {
getErrorMessage(errorCode?: string): string | undefined {
return getErrorMessage(errorCode);
}
}
// 单例实例
export const myModuleErrorCodeMapper = new MyModuleErrorCodeMapper();步骤 5:导出模块(index.ts)
在 index.ts 中导出模块的所有内容:
export * from './types';
export * from './api';
export * from './code'; // 如果有错误码映射步骤 6:在主入口文件中导出
在 src/index.ts 中添加新模块的导出:
export * from './types';
export * from './baseClient';
export * from './client';
export * from './module/liveStreamRoom';
export * from './module/myModule'; // 添加新模块完整示例
参考 src/module/liveStreamRoom/ 目录下的实现,这是一个完整的模块示例:
- types.ts: 定义了
ListActivityAPIRequest、ListActivityAPIResponse等类型,以及ILiveStreamRoomAPI接口 - api.ts: 实现了
LiveStreamRoomModule类,包含listActivityAPI方法 - index.ts: 导出所有内容
使用新模块
添加完成后,可以这样使用:
import { VolClient, MyModule } from '@be-link/volcengine-openapi-sdk-node';
const client = new VolClient({
region: 'cn-beijing',
service: 'myservice',
host: 'myservice.volcengineapi.com',
});
const myModule = new MyModule(client);
const response = await myModule.myAPI({
param1: 'value1',
param2: 123,
});