AWS CDK + API Gateway and Integrations. A little guide how to.

By Danilo Desole

| 3 minutes read

I’ve been working with CDK and I think is brilliant, the way it lets you define resources and infrastructure using your favorite coding language is awesome, I personally use Python. Sometimes what happens is that CDK takes over a lot of control and creates resources as it thinks is proper… Also, documentation lacks some advanced configuration.

For instance, I come across this AWS documentation page to develop a proxy to S3 using API Gateway. I thought to reproduce the same in CDK, but I faced some issues in defining the integrations.

In this post, I’m going to show how I created the API Gateway, the challenges I faced, and how I solved them, with the hope it might help you too!

So let’s start from the beginning.

Defining REST APIs

To define a REST API you can use the following snippet, in a single row, in CDK, you can define a new set of REST API

my_apig = apig.RestApi(self, "ApigAndS3")

Defining Resources

Now it’s time to define a couple of resources, to be clear our final goal is to create something like the following: http://myapigateway/bucketName/item where bucketName and item are placeholder the client will pass along with a request body. Whatever is passed in the body will be saved in bucketName/item. Of course, you need to own write permissions on the bucket defined by bucketName. Here again, a couple of lines define two resources. Awesome!

Defining the integration

Here I started to sweat, as defining the integrations per se is not complicated

bucket_integration = apig.AwsIntegration(service="s3", integration_http_method="PUT", path="{bucket}/{object}", region="eu-west-1", options=integration_options)

Is the integration_options really hard to define, considering I got the error apigateway Invalid mapping expression parameter specified: method.request.path. many, many, times… I couldn’t find an answer online and even the AWS Post here added confusion.

First: what are integration options? Well in integration options you can define how API Gateway will integrate with the defined service, in particular, you can map URL/Body parameters with parameters for your integration. What we aim to do is to use the URL path parameters bucketName/item to define the S3 path where to save the request body payload.

In the AWS console, you do something like this, very far from what you do in CDK

Image description

Instead in CDK, you will define something like

integration_response = apig.IntegrationResponse(status_code="200")
integration_options = IntegrationOptions(request_parameters={        "integration.request.path.bucket":"method.request.path.bucketName",          "integration.request.path.object":"method.request.path.item",credentials_role=role, 
integration_responses=[integration_response])

As you can notice the correct path URL to be passed are integration.request.path.bucket and integration.request.path.object mapped to method.request.path.bucketName and method.request.path.item.

What really helped me is the CLI, commands

aws apigateway get-integration --rest-api-id abcd --resource-id 1234 --http-method POST
aws apigateway get-method --rest-api-id abcd --resource-id 1234 --http-method POST

Final thoughts

CDK is really cool, the documentation needs to be expanded to care also for advanced scenarios, and be extensive to describe all you can actually do.

Use the CLI when in doubt… This always helps.

The full code for this mini-POC can be found here.

If your organisation is scaling its AWS usage and needs help in implementing AWS Guardrails, AWS Control Tower, AWS Landing Zones, and any other AWS Service, please feel free to reach out by visiting our contact page or sending an email to team@virtuability.com.