【发布时间】:2020-02-12 15:04:06
【问题描述】:
我正在构建一个需要接受文件上传的 API。所以用户可以POST一个文件到一个端点,该文件将被发送到病毒扫描,然后如果它是干净的将被发送到存储(可能是S3)。到目前为止,我已经通过一个问题实现了这一点:文件临时保存在应用程序文件系统中。我需要设计一个不在内存中存储东西的应用程序。这是我目前工作的代码:
app.js
const express = require('express');
const bb = require('express-busboy');
const app = express();
// Busboy modules extends the express app to handle incoming files
bb.extend(app, {
upload: true,
path: './tmp'
});
Routes.js
const express = require('express');
const router = express.Router();
const fileManagementService = require('./file-management-service')();
router
.route('/:fileId')
.post(async (req, res, next) => {
try {
const {fileId} = req.params;
const {files} = req;
const response = await fileManagementService.postFile(files, fileId);
res.status(201).json(response);
} catch (err) {
next(err);
}
})
文件管理服务.js
const fs = require('fs');
function createUploader() {
// POST /:fileId
async function postFile(data, fileId) {
const {file} = data.file;
const fileStream = fs.createReadStream(file);
const scanOutput = await scanFile(fileStream); // Function scans file for viruses
const status = scanOutput.status === 'OK';
let upload = 'NOT UPLOADED';
if (status) {
upload = await postS3Object({file}); // Some function that sends the file to S3 or other storage
}
fs.unlinkSync(file);
return {
fileId,
scanned: scanOutput,
upload
};
}
return Object.freeze({
postFile
});
}
module.exports = createUploader;
如前所述,上述工作按预期工作,文件被发送以进行扫描,然后发送到 S3 存储桶,然后将响应返回给发布者。然而,我的 express-busboy 实现是将文件存储在 ./tmp 文件夹中,然后我使用 fs.createReadStream(filePath); 将其转换为可读流,然后将其发送到 AV 并再次在将文件发送到 S3 的函数中。
此 API 托管在 Kubernetes 集群中,我需要避免创建状态。如何在不实际保存文件的情况下实现上述目标?我猜 busboy 会以某种流的形式接收这个文件,所以听起来不密集,它能否不只是保持流并通过这些函数通过管道传输以达到相同的结果?
【问题讨论】:
标签: node.js express busboy nodejs-stream