Express.js Integration
This guide explains how to integrate FileZen with Express.js applications using the @filezen/js package. This package provides a ZenStorage class that simplifies file upload and management operations with comprehensive error handling and automatic multipart upload support.
Code Example: See the complete Node.js Express server example for a working implementation with interactive test interface.
Installation
Install the FileZen JavaScript SDK:
Quick Start
1. Environment Configuration
Set your FileZen API key as an environment variable. This can be done in your local .env file during development or as a system environment variable in production.
FILEZEN_API_KEY=your_api_key_hereThe FileZen SDK automatically detects the FILEZEN_API_KEY environment variable for server-side operations, so no additional configuration is needed in your server setup. The keepUploads option defaults to false for server-side usage, so temporary uploads are automatically cleaned up.
2. Initialize ZenStorage
Create a ZenStorage instance with your configuration. The SDK will automatically detect the FILEZEN_API_KEY from your environment variables.
import { ZenStorage } from '@filezen/js';
// Initialize storage with automatic environment variable detection
const zenStorage = new ZenStorage({
apiKey: "your_api_key_here", // Optional: can use FILEZEN_API_KEY env var
});3. Upload Files
You can now use the ZenStorage instance to upload files with various methods.
import fs from 'fs';
// Upload a single file from file path
const fileBuffer = fs.readFileSync(filePath);
const upload = await zenStorage.upload(fileBuffer, {
name: 'my-file.jpg',
mimeType: 'image/jpeg',
});
if (upload.error) {
console.error('Upload failed:', upload.error);
} else {
console.log('File uploaded:', upload.file.url);
}FileZen Functions
Single File Upload
Upload individual files with error handling.
import fs from 'fs';
async function uploadSingleFile(filePath, filename, mimeType) {
const fileBuffer = fs.readFileSync(filePath);
const upload = await zenStorage.upload(fileBuffer, {
name: filename,
mimeType: mimeType,
});
if (upload.error) {
throw new Error(`Upload failed: ${upload.error.message}`);
}
return {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
};
}Bulk Upload
Upload multiple files concurrently for better performance.
async function uploadMultipleFiles(filesData) {
const uploadItems = filesData.map(file => ({
source: Buffer.from(file.buffer),
options: {
name: file.originalname,
mimeType: file.mimetype,
},
}));
const uploads = await zenStorage.bulkUpload(...uploadItems);
// Check for any upload errors
const failedUploads = uploads.filter(upload => upload.error);
if (failedUploads.length > 0) {
const failures = failedUploads.map(upload => ({
name: upload.name || 'unknown',
error: upload.error?.message || 'Unknown error'
}));
throw new Error(`${failedUploads.length} uploads failed`);
}
return uploads.map(upload => ({
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
}));
}Upload from URL
Upload files directly from external URLs.
async function uploadFromUrl(sourceUrl, fileName) {
const upload = await zenStorage.uploadFromUrl(sourceUrl, {
name: fileName || 'downloaded-file',
});
if (upload.error) {
throw new Error(`URL upload failed: ${upload.error.message}`);
}
return {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
};
}Upload from Base64
Upload files from base64 encoded data.
async function uploadFromBase64(base64Data, fileName, mimeType) {
const upload = await zenStorage.uploadFromBase64(base64Data, {
name: fileName || 'base64-file',
mimeType: mimeType,
});
if (upload.error) {
throw new Error(`Base64 upload failed: ${upload.error.message}`);
}
return {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
};
}Manual Multipart Upload Control
For fine-grained control over multipart uploads, especially for large files or when you need to track progress:
async function manualMultipartUpload(file, fileName, mimeType) {
// Start multipart upload session
const { id: sessionId } = await zenStorage.multipart.start({
fileName: fileName,
mimeType: mimeType,
totalSize: file.size,
uploadMode: 'STREAMING',
metadata: { type: 'manual_upload' }
});
let uploadedSize = 0;
const chunkSize = 5 * 1024 * 1024; // 5MB chunks
// Upload file in chunks
while (uploadedSize < file.size) {
// Create a chunk from the current position
const chunk = file.slice(
uploadedSize,
Math.min(file.size, uploadedSize + chunkSize)
);
// Upload this specific chunk
await zenStorage.multipart.uploadPart({
sessionId: sessionId,
chunk: chunk
});
// Update progress
uploadedSize = Math.min(file.size, uploadedSize + chunkSize);
console.log(`Uploaded ${uploadedSize}/${file.size} bytes`);
}
// Finalize the multipart upload
const result = await zenStorage.multipart.finish({
sessionId: sessionId
});
return result;
}Generate Signed URL
Generate secure signed URLs for direct uploads from client applications.
function generateUploadUrl(fileKey, expirationTime = 3600) {
const signedUrl = zenStorage.generateSignedUrl({
path: '/files/upload',
fileKey: fileKey,
expiresIn: expirationTime, // 1 hour by default
});
return {
signedUrl: signedUrl,
expiresIn: expirationTime,
};
}Delete File
Delete files by their URL.
async function deleteFile(fileUrl) {
try {
await zenStorage.deleteByUrl(fileUrl);
return { success: true, message: 'File deleted successfully' };
} catch (error) {
throw new Error(`Failed to delete file: ${error.message}`);
}
}Complete Express.js Server Example
Here’s a complete Express.js server implementation with all FileZen endpoints.
Framework Dependencies: This example uses express, multer, and cors packages for the server setup. Install them with: npm install express multer cors. These are just for the example - you can use any file upload handling method with FileZen.
import express from 'express';
import multer from 'multer';
import cors from 'cors';
import { ZenStorage } from '@filezen/js';
const app = express();
const port = process.env.PORT || 3001;
// Middleware
app.use(cors());
app.use(express.json());
// Initialize FileZen storage
const zenStorage = new ZenStorage();
// Configure multer for file uploads
const upload = multer({
limits: {
fileSize: 100 * 1024 * 1024, // 100MB limit
},
});
// Health check
app.get('/', (req, res) => {
res.json({ message: 'FileZen Express.js Server Running' });
});
// Single file upload
app.post('/api/files/upload', upload.single('file'), async (req, res) => {
try {
if (!req.file) {
return res.status(400).json({
success: false,
error: 'No file provided'
});
}
const fileBuffer = Buffer.from(req.file.buffer);
const upload = await zenStorage.upload(fileBuffer, {
name: req.file.originalname,
mimeType: req.file.mimetype,
});
if (upload.error) {
return res.status(400).json({
success: false,
error: upload.error.message
});
}
res.json({
success: true,
file: {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
},
});
} catch (error) {
console.error('Upload error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
});
// Bulk file upload
app.post('/api/files/bulk-upload', upload.array('files', 10), async (req, res) => {
try {
if (!req.files || req.files.length === 0) {
return res.status(400).json({
success: false,
error: 'No files provided'
});
}
const uploadItems = req.files.map(file => ({
source: Buffer.from(file.buffer),
options: {
name: file.originalname,
mimeType: file.mimetype,
},
}));
const uploads = await zenStorage.bulkUpload(...uploadItems);
const results = uploads.map(upload => {
if (upload.error) {
return { error: upload.error.message };
}
return {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
};
});
res.json({
success: true,
files: results,
});
} catch (error) {
console.error('Bulk upload error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
});
// Upload from URL
app.post('/api/files/upload-from-url', async (req, res) => {
try {
const { url, name } = req.body;
if (!url) {
return res.status(400).json({
success: false,
error: 'URL is required'
});
}
const upload = await zenStorage.uploadFromUrl(url, {
name: name || 'downloaded-file',
});
if (upload.error) {
return res.status(400).json({
success: false,
error: upload.error.message
});
}
res.json({
success: true,
file: {
url: upload.file.url,
name: upload.file.name,
size: upload.file.size,
mimeType: upload.file.mimeType,
},
});
} catch (error) {
console.error('URL upload error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
});
// Generate signed URL
app.post('/api/files/generate-signed-url', async (req, res) => {
try {
const { fileKey, expiresIn = 3600 } = req.body;
if (!fileKey) {
return res.status(400).json({
success: false,
error: 'fileKey is required'
});
}
const signedUrl = zenStorage.generateSignedUrl({
path: '/files/upload',
fileKey: fileKey,
expiresIn: expiresIn,
});
res.json({
success: true,
signedUrl: signedUrl,
expiresIn: expiresIn,
});
} catch (error) {
console.error('Signed URL generation error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
});
// Delete file
app.delete('/api/files/delete', async (req, res) => {
try {
const { url } = req.body;
if (!url) {
return res.status(400).json({
success: false,
error: 'File URL is required'
});
}
await zenStorage.deleteByUrl(url);
res.json({
success: true,
message: 'File deleted successfully',
});
} catch (error) {
console.error('Delete error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
});
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});