Le contexte :
Application Node.js / Loopback dont la base de données est alimentée par un fichier .zip contenant des données provenant d'applications CRM d'entreprise existantes. J'essaie de stocker un binaire du fichier .zip dans ma base de données à des fins de débogage de production en utilisant GridFS car le fichier peut être >16mb et le récupérer à tout moment en utilisant un point de terminaison d'administration.
Problème :
Je peux stocker le fichier zip avec la fonction storeLatestZipFile
dans mon module et je peux le récupérer en utilisant un point de terminaison que la fonction createLatestZipEndpoint
crée.
Cependant, le fichier .zip que je reçois est plus volumineux que le fichier original (14,7 mb contre 21,1 mb) et il est également corrompu.
Je suppose que je ne code pas mes données ou que je n'utilise pas correctement l'API GridFS. Quelqu'un aurait-il repéré les erreurs dans mon code / aurait-il plus d'expérience dans le stockage des .zips avec GridFS ?
Le module en question :
const { pino } = require('amf-logger');
const fs = require('fs');
const mongo = require('mongodb');
const log = pino({ name: 'bot-zip-upload-storage' });
/**
* @param {string} path Path to the zip file to be persisted.
* @param {object} app Loopback application instance.
*/
function storeLatestZipFile(path = './', app = {}) {
log.info('**** Starting streaming current uploaded zip to DB ****');
const zipReadStream = fs.createReadStream(path, { encoding: 'binary' });
const { db } = app.dataSources.mongo.connector;
const bucket = new mongo.GridFSBucket(db);
bucket.delete('zipfile', () => {
log.info('deleted old zipfile');
const uploadStream = bucket.openUploadStreamWithId(
'zipfile',
`bot-data-${new Date().toISOString()}`,
{
contentType: 'application/zip'
}
);
zipReadStream.pipe(uploadStream);
});
}
/**
* @param {object} app Loopback application instance.
*/
async function createLatestZipEndpoint(app = {}) {
if (!app.get) {
log.error("app object does not have 'get' property.");
return;
}
app.get('/api/admin/latestzip', async (req, res) => {
if (!req.headers.latestfile || req.headers.latestfile !== process.env.ADMIN_LATESTFILE) {
res.sendStatus(403);
return;
}
try {
const { db } = app.dataSources.mongo.connector;
const bucket = new mongo.GridFSBucket(db);
res.writeHead(200, { 'Content-Type': 'application/zip' });
const downloadStream = bucket.openDownloadStream('zipfile');
log.info('download stream opened, begin streaming');
downloadStream.pipe(res);
} catch (err) {
log.error(`error getting zipfile: ${err}`);
res.sendStatus(500);
}
});
}
module.exports = {
storeLatestZipFile,
createLatestZipEndpoint
};