3

We have an API that has multiple different endpoints, as you'd expect. We have the requirement to add a new endpoint which will return an application/pdf along with the file data.

To do this, we return the following:

return {
        statusCode: 200,
        headers: {
          'Content-Type': 'application/pdf',
          'Content-disposition': `attachment; filename=${filename}.pdf`,
          'Accept': 'application/pdf',
        },
        body: fileData,
        isBase64Encoded: true,
      };

The isBase64Encoded only works when a binary media type is set in the API Gateway. As detailed here: https://medium.com/@ngchiwang/aws-api-gateway-lambda-return-binary-image-ba8faa660839

The issue we have is that by setting the binary media type to * / * (no spaces) on the API Gateway, this, in turn, affects all other endpoints on the API.

Example This breaks one endpoint on the OPTIONS cors check, returning an InternalServerErrorException without reason. This endpoint is just a GET with no data in the request.

Does this mean we need a separate API just for this one endpoint, or is there a way we can include this in the same APIG?

For further clarification, this is a POST that includes a small amount of JSON in the request: {"someValue":1234} and returns the above application/pdf content type.

StuartM
  • 6,743
  • 18
  • 84
  • 160
  • Did you solve this issue? The only way I have gotten close to solving it is by switching the endpoint from a proxied lambda integration to a non proxied lambda integration. though that throws up it's own issues. – Jarede May 25 '21 at 15:59

1 Answers1

-2

I'm just tackling this issue and resolved it like this:

  1. Send base 64 string just as normal json response and handle the pdf part on the client
const sendRes = (status:number, body:any) => {
  var response = { statusCode: status, headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) };
  return response;
};
  return sendRes(201, {pdf:your-base64-string} );
  1. Then on the client (Nuxt in my case):
 let res = await this.$store.dispatch('pdf/makePdf')

      const linkSource = `data:application/pdf;base64,${res.data.pdf}`;
      const downloadLink = document.createElement("a");
      const fileName = "your-pdf-filename.pdf";
      downloadLink.href = linkSource;
      downloadLink.download = fileName;
      downloadLink.click();

This open a download window and lets you save the file locally

martinval
  • 459
  • 4
  • 19