告别数据孤岛:Maxun存储API全方位解析与实战指南
作为一款开源无代码Web数据提取平台,Maxun(GitHub推荐项目精选 / ma / maxun)的核心优势在于其强大的数据处理能力。而支撑这一能力的关键组件,正是本文将要深入探讨的存储API体系。无论是自动化工作流录制文件的管理,还是大规模数据提取结果的持久化,Maxun的存储接口都扮演着不可或缺的角色。本文将从架构设计到实际应用,全面解析Maxun存储API的实现细节与使用方法,帮助开发者和运营人员更好地利用这一强大工具。
存储API架构概览
Maxun的存储系统采用了分层设计,结合了关系型数据库、对象存储和文件系统存储三种方案,以满足不同场景下的数据存储需求。这一架构不仅保证了数据的可靠性和可扩展性,还优化了不同类型数据的存储效率。
多维度存储架构
Maxun的存储系统主要由以下几个核心模块构成:
-
关系型数据库存储:基于PostgreSQL,用于存储结构化数据如用户信息、工作流元数据等。核心实现位于server/src/storage/db.ts。
-
对象存储:使用MinIO作为对象存储服务,主要用于存储二进制数据如截图、大型文件等。相关实现可参见server/src/storage/mino.ts。
-
文件系统存储:用于存储工作流录制文件等中等大小的文本数据。核心功能实现于server/src/workflow-management/storage.ts。
这种多层次的存储架构使得Maxun能够高效处理各种类型的数据,同时保持系统的灵活性和可扩展性。
存储API调用流程
Maxun存储API的调用遵循前后端分离的架构模式。前端通过Axios发送HTTP请求,后端则根据请求类型调用相应的存储服务。以下是一个典型的存储API调用流程:
- 前端组件(如录制表格)调用src/api/storage.ts中的函数。
- 这些函数通过Axios向后端发送HTTP请求。
- 后端路由(如server/src/routes/storage.ts)接收请求并调用相应的服务。
- 服务层代码调用底层存储实现(db.ts, mino.ts等)完成实际的数据操作。
- 结果通过API返回给前端,更新UI展示。
核心存储接口详解
Maxun的存储API提供了丰富的接口,涵盖了从简单的文件读写到复杂的工作流数据管理等各个方面。下面我们将详细介绍几个核心接口及其实现。
关系型数据库接口
Maxun使用Sequelize作为ORM工具,封装了与PostgreSQL的交互。核心实现位于server/src/storage/db.ts。
该模块提供了数据库连接和同步功能:
export const connectDB = async () => {
try {
await sequelize.authenticate();
console.log('Database connected successfully');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
};
export const syncDB = async () => {
try {
const isDevelopment = process.env.NODE_ENV === 'development';
await sequelize.sync({
force: false,
alter: isDevelopment
});
console.log('Database synced successfully!');
} catch (error) {
console.error('Failed to sync database:', error);
}
};
这段代码展示了Maxun如何建立数据库连接并同步模型结构。值得注意的是,alter: isDevelopment配置确保了在开发环境下可以自动调整表结构,而在生产环境中则禁止这一操作,以保证数据安全。
对象存储接口
对于二进制数据如截图的存储,Maxun采用了MinIO对象存储。相关实现位于server/src/storage/mino.ts。
核心功能由BinaryOutputService类提供:
class BinaryOutputService {
private bucketName: string;
constructor(bucketName: string) {
this.bucketName = bucketName;
}
async uploadAndStoreBinaryOutput(run: Run, binaryOutput: Record<string, any>): Promise<Record<string, string>> {
// 实现细节略
}
async uploadBinaryOutputToMinioBucket(run: Run, key: string, data: Buffer): Promise<void> {
// 实现细节略
}
public async getBinaryOutputFromMinioBucket(key: string): Promise<Buffer> {
// 实现细节略
}
}
这个服务类封装了将二进制数据上传到MinIO、从MinIO获取数据以及更新数据库记录等功能。通过这种方式,Maxun实现了二进制数据的高效存储和访问。
文件系统存储接口
对于工作流录制文件等文本数据,Maxun直接使用文件系统进行存储。相关实现位于server/src/workflow-management/storage.ts。
该模块提供了基本的文件操作功能:
export const readFile = (path: string): Promise<string> => {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
};
export const saveFile = (path: string, data: string): Promise<void> => {
return new Promise((resolve, reject) => {
fs.writeFile(path, data, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
};
export const deleteFile = (path: string): Promise<void> => {
return new Promise((resolve, reject) => {
fs.unlink(path, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
};
这些函数将Node.js的文件系统操作Promise化,使得异步文件操作更加直观和易于管理。
前端存储API调用示例
Maxun的前端应用通过封装好的API函数与后端存储服务交互。这些API函数集中定义在src/api/storage.ts中。下面我们以录制文件的管理为例,介绍几个常用的API调用。
获取存储的录制文件列表
export const getStoredRecordings = async (): Promise<string[] | null> => {
try {
const response = await axios.get(`${apiUrl}/storage/recordings`);
if (response.status === 200) {
return response.data;
} else {
throw new Error('Couldn\'t retrieve stored recordings');
}
} catch (error: any) {
console.log(error);
return null;
}
};
这个函数通过GET请求获取所有存储的录制文件列表,通常用于前端展示录制文件列表。
更新录制文件
export const updateRecording = async (id: string, data: {
name?: string;
limits?: Array<{pairIndex: number, actionIndex: number, argIndex: number, limit: number}>;
credentials?: Credentials;
targetUrl?: string
}): Promise<boolean> => {
try {
const response = await axios.put(`${apiUrl}/storage/recordings/${id}`, data);
if (response.status === 200) {
return true;
} else {
throw new Error(`Couldn't update recording with id ${id}`);
}
} catch (error: any) {
console.error(`Error updating recording: ${error.message}`);
return false;
}
};
这个函数允许更新录制文件的元数据,如名称、限制条件等。
删除录制文件
export const deleteRecordingFromStorage = async (id: string): Promise<boolean> => {
const hasRuns = await checkRunsForRecording(id);
if (hasRuns) {
return false;
}
try {
const response = await axios.delete(`${apiUrl}/storage/recordings/${id}`);
if (response.status === 200) {
return true;
} else {
throw new Error(`Couldn't delete stored recording ${id}`);
}
} catch (error: any) {
console.log(error);
return false;
}
};
这个函数用于删除录制文件,但在删除前会检查是否有相关的运行记录,以防止误删除。
实际应用场景:录制文件管理
为了更好地理解Maxun存储API的应用,我们以录制文件管理为例,介绍其在实际场景中的使用。
录制文件管理界面
Maxun的录制文件管理界面主要由src/components/robot/RecordingsTable.tsx组件实现。这个组件展示了存储的录制文件列表,并提供了各种管理功能。
export const RecordingsTable = ({
handleEditRecording,
handleRunRecording,
handleScheduleRecording,
handleIntegrateRecording,
handleSettingsRecording,
handleEditRobot,
handleDuplicateRobot }: RecordingsTableProps) => {
// 组件实现细节略
};
这个组件通过调用src/api/storage.ts中的函数,实现了录制文件的增删改查等功能。
录制文件管理流程
- 加载录制文件列表:组件挂载时,调用
getStoredRecordings函数获取录制文件列表。 - 展示录制文件:将获取到的录制文件列表展示在表格中。
- 执行操作:用户可以通过表格中的按钮执行各种操作,如运行、编辑、删除录制文件等。
- 更新界面:操作完成后,刷新录制文件列表,更新界面展示。
通过这种方式,Maxun实现了录制文件的完整生命周期管理,而这一切都依赖于前面介绍的存储API。
总结与展望
Maxun的存储API体系通过分层设计,结合了关系型数据库、对象存储和文件系统存储的优势,为无代码Web数据提取平台提供了强大而灵活的数据存储解决方案。从前端的API调用到底层的存储实现,Maxun都展现了良好的架构设计和代码组织。
随着Maxun的不断发展,存储API体系也将不断完善。未来可能的改进方向包括:
- 引入更灵活的存储策略,支持不同类型数据的自动分类存储。
- 增强数据备份和恢复功能,提高系统的可靠性。
- 优化大数据量场景下的存储性能,如引入缓存机制等。
通过持续优化存储API,Maxun将能够更好地满足用户在各种场景下的数据存储需求,为无代码Web数据提取提供更强大的支持。
官方文档:docs/self-hosting-docker.md 存储API源码:server/src/storage/ 前端API调用:src/api/storage.ts 录制管理组件:src/components/robot/RecordingsTable.tsx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



