Створення кастомного збереження Multer для завантаження файлів в S3 за допомогою Node.js

Коли працюєш з завантаженням файлів у Node.js, Multer часто є стандартним посередником. За замовчуванням Multer пропонує два механізми збереження:

pic

Джерело коду Multer

  1. DiskStorage: Зберігає файли на локальному диску сервера.
  2. MemoryStorage: Тимчасово зберігає файли в пам'яті як об'єкти Buffer.

Хоча ці опції є достатніми для багатьох випадків, вони можуть бути не зовсім підходящими для сценаріїв, коли потрібно:

  • Зберігати файли безпосередньо в хмарному сховищі (наприклад, AWS S3, Google Cloud Storage тощо).
  • Використовувати власну логіку чи робочий процес для обробки файлів, як-от правила іменування чи динамічний вибір сховища.

Тут на допомогу приходять кастомні механізми збереження. Multer дозволяє розробникам визначати власні механізми збереження для задоволення специфічних вимог.
У цій статті ми розглянемо, як створити кастомний механізм збереження Multer для завантаження файлів безпосередньо в AWS S3.

Для демонстрації того, як створити кастомний механізм збереження Multer, ми почнемо з побудови простого API на Node.js. Нижченаведений код встановлює основу для цього API:

Спочатку завантажте необхідні пакети:

npm install express multer aws-sdk uuid
//app.js  
const express = require('express');  
const app = express();  
const port = 3000;  
const uploadRoute = require('./routes/upload-files.route');  
app.get('/', (req, res) => {  
 res.json('Hello CustomStorage S3!');  
});  

app.use('/api', uploadRoute);  

app.listen(port, () => {  
 console.log(`Server listening on port ${port}`);  
});

Щоб реалізувати кастомний механізм збереження для AWS S3, центральною частиною буде основний метод, який обробляє процес завантаження файлів.
У нашій реалізації кастомного збереження, це метод _handleFile.

Нижче наведена реалізація кастомного механізму збереження.
Щоб налаштувати власний бакет S3, перегляньте:
https://console.cloud.google.com

const AWS = require('aws-sdk');  
const { v4: uuidv4 } = require('uuid'); // Для генерування унікальних імен файлів  

// Налаштування AWS S3  
const s3 = new AWS.S3({  
 endpoint: 'https://storage.googleapis.com',  
 credentials: {  
 accessKeyId: '',  
 secretAccessKey: ''  
 }  
}); // ЗАУВАЖЕННЯ: Замініть ці облікові дані на змінні середовища у виробничому середовищі!  

// Кастомний механізм збереження  
class S3StorageEngine {  
 constructor(bucketName) {  
 this.bucketName = bucketName; // Назва бакету, куди будуть завантажуватися файли  
 }  

 // Основний метод для обробки завантаження файлів  
 _handleFile(req, file, cb) {  
 console.log('Завантаження файлу', file.stream);  

 // Генерація унікального ключа для файлу  
 const key = `${uuidv4()}-${file.originalname}`;  

 // Визначення параметрів для завантаження в S3  
 const uploadParams = {  
 Bucket: this.bucketName,  
 Key: key,  
 Body: file.stream,  
 ContentType: file.mimetype,  
 };  

 // Завантаження файлу в S3  
 s3.upload(uploadParams, (err, data) => {  
 if (err) {  
 console.log('Помилка під час завантаження файлу', err);  
 return cb(err); // Виклик зворотного зв'язку з помилкою  
 }  

 // Виклик зворотного зв'язку з метаданими файлу  
 cb(null, {  
 key: data.Key,  
 location: data.Location,  
 });  
 });  
 }  

 // Опційний метод для видалення файлів  
 _removeFile(req, file, cb) {  
 const deleteParams = {  
 Bucket: this.bucketName,  
 Key: file.key,  
 };  

 s3.deleteObject(deleteParams, (err) => {  
 if (err) {  
 return cb(err); // Виклик зворотного зв'язку з помилкою  
 }  
 cb(null); // Виклик зворотного зв'язку успішно  
 });  
 }  
}  

module.exports = S3StorageEngine;

Тепер, коли ми створили кастомний механізм збереження для S3, давайте подивимося, як використовувати його в API для обробки завантажень та видалень файлів.

Ось реалізація:

const express = require('express');  
const S3StorageEngine = require('../storage/multer-s3-custom-storage');  
const multer = require('multer');  

const customStorage = new S3StorageEngine('sayman-bucket'); // Замініть 'sayman-bucket' на вашу фактичну назву бакету  
const router = express.Router();  
const upload = multer({ storage: customStorage });  

// Маршрут для обробки завантаження файлів  
router.post('/upload', upload.single('file'), (req, res) => {  
 res.json({  
 file: req.file, // Повертає метадані завантаженого файлу  
 });  
});  

// Маршрут для обробки видалення файлів  
router.delete('/delete/:key', (req, res) => {  
 const file = {  
 key: req.params?.key, // Ключ файлу для видалення з S3  
 };  

 // Використовуємо метод _removeFile кастомного механізму збереження для видалення файлу  
 customStorage._removeFile(req, file, (err) => {  
 if (err) {  
 return res.status(500).json({  
 message: 'Помилка під час видалення файлу',  
 error: err.message,  
 });  
 }  
 res.json({ message: 'Файл успішно видалено' });  
 });  
});  

module.exports = router;

З цією реалізацією ви тепер маєте повністю функціональне API для завантаження та керування файлами в AWS S3 за допомогою кастомного механізму збереження Multer!

У цій статті ми показали, як створити кастомний механізм збереження Multer для завантаження файлів безпосередньо в AWS S3.
Хоча це покриває основи використання Multer для кастомного збереження, розуміння того, як Multer обробляє файли "під капотом" є ключем до розкриття його повного потенціалу.

У наступній статті я поглиблюсь у:

  • Як Multer перехоплює потоки файлів.

Перекладено з: Building Custom Multer Storage for S3 File Uploads with Node.js

Leave a Reply

Your email address will not be published. Required fields are marked *