pulumi / pulumi-aws-apigateway

Apache License 2.0
11 stars 5 forks source link

How to avoid base64 encoded body in awsx.apigateway.API #30

Open mstn opened 4 years ago

mstn commented 4 years ago

Hi, I have a simple gateway

const api = new awsx.apigateway.API('api',  {
  routes: [
    {
      path: '/',
      method: 'POST',
      eventHandler: myLambda,
    },
  ],
});

Where myLambda is an instance of aws.lambda.Function.

When I run the code, event.body is encoded in base64. I think the gateway does that. Am I wrong?

How can I tell the gateway to leave the body raw?

leezen commented 4 years ago

You'll need to setup your integration and content handling such that API Gateway will give you back text. See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html and https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-workflow.html

What might be easier is checking the isBase64Encoded in your function, then decoding as necessary.

mstn commented 4 years ago

Yep, I am checking isBase64Encoded now.

I was wondering if it was possible to setup this behavior using Pulumi API. In theory (I haven't checked) AWS API should allow that since it should be the default behavior with Severless Framework, for example.

Not a big issue. Probably, I should check `isBase64Encoded' always anyway.

Thanks!

leezen commented 4 years ago

I see -- right, there's no 'convenience' way to indicate that you prefer raw text at the moment via awsx without setting up the various parameters yourself. That's definitely a great suggestion!

cabeaulac commented 3 years ago

I would also like this feature to set the base64 encoding boolean using awsx.apigateway.API

cabeaulac commented 3 years ago

In the meantime let body; if (event.body !== null && event.body !== undefined) { console.log("Event "); console.log(JSON.stringify(event)); if (event.isBase64Encoded) { body = JSON.parse(Buffer.from(event.body, 'base64').toString('utf8')); } else { body = JSON.parse(event.body); } console.log(JSON.stringify(body)); }

muhannad0 commented 3 years ago

I've also had a run in with the same issue past couple of days. I found that setting the parameter binaryMediaTypes: [] in the restApiArgs when using awsx.apigateway.API stops API Gateway from always encoding the payload data for POST requests.

Here's a sample Pulumi code:

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

const api = new awsx.apigateway.API("api", {
  routes: [
    {
      path: "/hello",
      method: "POST",
      eventHandler: async (event) => {

        if (event.body) {
          let data = JSON.parse(event.body);

          console.log(data);
          return {
            statusCode: 200,
            body: JSON.stringify({ payload: data })
          }
        }
        return {
          statusCode: 400,
          body: JSON.stringify({ error: "Bad request", request: event })
        }
      }
    },
  ],
  restApiArgs: {
    binaryMediaTypes: [],
  },
});

export const apiUrl = api.url;

Testing out the endpoint using curl:

curl $(pulumi stack output apiUrl)/hello \
-H 'Content-Type: application/json' \
-d '{ "message": "hello" }'

{"payload":{"message":"Hello World"}}

Side note: I'm not too sure of the implications setting this parameter and how it affects when uploading binary data to an endpoint. I'm also learning how to use Pulumi to build serverless applications on AWS. Maybe someone can chime in with a better explanation. :v:

@cabeaulac thanks for bringing this up and posting the workaround.