Отправить Тело Ответа Лямбда-Обработчика В Виде Потока

#node.js #amazon-s3 #aws-lambda #response #serverless-framework

Вопрос:

Похоже, что есть миллион вопросов, связанных с моими, но ни одно из предложенных решений не работает или просто отличается настолько, что они мне не помогают.

У меня есть пользовательский интерфейс с кнопкой загрузки, где пользователи могут получать zip-файлы из S3, но в моей функции lambda, которая должна это выполнять, я получаю несколько ошибок.

У меня есть рабочее решение с использованием Express, но теперь мне нужно вместо этого использовать бессерверную платформу.

Вот мое рабочее решение в рамках Express:

 const zip = new AdmZip(data.Body);
const entries = zip.getEntries();
let newZip = new AdmZip();
for(let entry of entries){
    newZip.addFile(entry.entryName, entry.getCompressedData());
}
newZip.writeZip(__dirname   `/${file}.zip`);
let fileToSend = fs.createReadStream(`${file}.zip`);
fileToSend.pipe(res);
 

Где я использую AdmZip, по сути, для создания нового zip-файла из загруженного буфера, а затем отправляю его объекту ответа в виде потока, который определенно является хакерским, но работает, поэтому я был доволен им на данный момент.

Я попробовал аналогичное решение с использованием бессерверной платформы и лямбда-функции, которая выглядит следующим образом:

 const fs = require('fs/promises');
module.exports.handler = async (event) => {
       const response = {
          isBase64Encoded: false,
          statusCode: 200,
       };

       try {
        const params = {
            Bucket: BUCKET_NAME,
            Key: decodeURIComponent(event.pathParameters.fileKey),
        };
        const data = await s3.getObject(params).promise();
        const zip = new AdmZip(data.Body);
        const entries = zip.getEntries();
        let newZip = new AdmZip();
        for(let entry of entries){
            newZip.addFile(entry.entryName, entry.getCompressedData());
        }
        newZip.writeZip(__dirname   `/${fileName}.zip`);
        var fileToSend = fs.createReadStream(`${fileName}.zip`);
        fileToSend.pipe(response.body);
       } catch (error) {
         console.error(error);
         response.body = JSON.stringify({ message: 'Failed To Get File', errorMessage: error });
         response.statusCode = 500;
    }
return response;
};
 

Но при использовании этого кода он успешно создает файл в локальном каталоге, но выдает ошибку
TypeError: fs.createReadStream не является функцией

Что я изучил, и, похоже, это проблема с обещаниями, но я совершенно невежествен, когда дело доходит до потоков.

На данный момент я бы хотел, чтобы кто-нибудь помог мне либо отредактировать мой существующий код, либо указать мне совершенно другое направление.

Заранее спасибо

Комментарии:

1. fs/promises не имеет createReadStream метода, вместо этого вам нужно получить его от: const { createReadStream } = require('fs'); , дайте мне знать, если это решит вашу проблему

2. Я добавил const { createReadStream } = require('fs'); и реализовал с let fileToSend = createReadStream(``${event.pathParameters.fileKey}.zip``); помощью, но я получил ошибку: Ошибка типа : Не удается прочитать свойство «включено» неопределенного

3. как насчет использования этого кода? fs.createReadStream(__dirname ``/${fileName}.zip``);

4. @tam.teixeira, у которого были аналогичные результаты, но я думаю, что проблема связана с тем, что «Объект ответа должен быть совместим с JSON.stringify» ( ссылка на документацию AWS). Поэтому я не уверен, куда идти дальше, если это ограничение обработчика Лямбда