I am in the process of migrating my NodeJS project to API Gateway and I cannot figure out how to download a file from Lambda.
Here is a snippet of the response code on my local Node project.
app.get('/downloadPDF', function (req, res) {
res.setHeader('Content-disposition', 'attachment; filename=test.pdf');
res.setHeader('Content-type', 'application/pdf');
var PdfPrinter = require('pdfmake');
var printer = new PdfPrinter(fonts);
var pdfDoc = printer.createPdfKitDocument(dd);
pdfDoc.pipe(res);
pdfDoc.end();
});
Piping to the response I was able to get back a PDF.
Here is a snippet of my lambda function using serverless.
module.exports.createPDF = (event, context) => {
var PdfPrinter = require('pdfmake');
var printer = new PdfPrinter(fonts);
var pdfDoc = printer.createPdfKitDocument(dd);
pdfDoc.pipe(res);
pdfDoc.end();
}
Here is the endpoint in my serverless.yml
createPDF:
handler: functions.myFunction
events:
- http:
path: services/getPDF
method: get
response:
headers:
Content-Type: "'application/pdf'"
Content-disposition: "'attachment; filename=test.pdf'"
I don't know how to get reference to the response object in Lambda to pipe to. Is that possible? Is there another way?
Update
I ended up solving this issue by returning the base64 encoded PDF binary in a JSON response and decoding on the client. Note: using the base64 decoding in the response mapping template did not work.
Sample code:
var buffers = [];
pdfDoc.on('data', buffers.push.bind(buffers));
pdfDoc.on('end', function () {
var bufCat = Buffer.concat(buffers);
var pdfBase64 = bufCat.toString('base64');
return cb(null,
{"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": pdfBase64});
});