Two ways to directly integrate AWS Lambda function with Amazon API Gateway
Tags: aws, serverless, apigw, lambda
Published: 2022-07-17 04:04:46

---
title: Two ways to directly integrate AWS Lambda function with Amazon API Gateway
published: true
description: One could integrate API Gateway and AWS Lambda using the _proxy_ or _non-proxy_ integration. When to use which?
tags: aws, serverless, apigw, lambda
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5w6pfppecfqlzazgbrc1.jpg
---
Since the inception of the concept of "serverless", the combination of [Amazon API Gateway](https://aws.amazon.com/api-gateway/) and [AWS Lambda](https://aws.amazon.com/lambda/) function has become one of the most popular serverless patterns on AWS.

With the advent of deployment frameworks like [AWS CDK](https://aws.amazon.com/cdk/) or [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html), it has never been easier, using IaC, to deploy this pattern for the world to see.

As with many things in programming and computer science, there are often multiple ways to do something. The integration of API Gateway with the Amazon Lambda function is no different – one could use the _proxy_ and _non-proxy_ integration type.

This blog post will discuss the difference between the _proxy_ and _non-proxy_ integration and in which situations you might want to use a given integration method.

> The _proxy_ and _non-proxy_ are used here **only in the context of the integration type** and have nothing to do with [service proxies or proxy resources](https://www.alexdebrie.com/posts/api-gateway-elements/#vocabulary-time-service-proxies-vs-proxy-integrations-vs-proxy-resources).

## The _proxy_ integration

I would argue that the _proxy_ integration type is the most commonly deployed one. Partly because, to my knowledge, it is the default one that most of the deployment frameworks utilize, and partly because it is relatively light on the configuration side of things.

The following is a simplified diagram of the API Gateway integration with the AWS Lambda function via the _proxy_ type.

> Note that all the diagrams in this article omit concepts related to authorization and authentication as they are not relevant to the ideas presented in the text.

![_proxy_ integration type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/orm0kp513lp2suqk70up.jpeg)

- **With the _proxy_ integration, you lose the ability to perform data manipulation directly via the API Gateway mapping templates**.

  - Since you cannot use the mapping templates and the VTL, your function code might be a bit more complex than the _non-proxy_ counterpart.

- Very light on the configuration side of things. The IaC declaration is relatively easy to maintain.

- You **still able to take advantage of the API Gateway validation models**. A feature that, in my humble opinion, is underutilized.

> Before using the API Gateway validation models, consider reading [this article](https://rboyd.dev/089999bf-b973-42ed-9796-6167539269b8) as it surfaces some of the issues you might encounter.

For completeness' sake, here is the minimal configuration required to integrate the API Gateway with an AWS Lambda function using AWS CDK and [TypeScript](https://www.typescriptlang.org/).

```ts
const api = new aws_apigateway.RestApi(this, "API", {});

const handler = new aws_lambda_nodejs.NodejsFunction(this, "Handler", {
  entry: join(__dirname, "./handler.ts")
});

api.root.addMethod("GET", new aws_apigateway.LambdaIntegration(handler));
```

Pretty minimal, right? Now, onto the _non-proxy_ integration type.

## The _non-proxy_ integration type

It took me a while to familiarize myself with some of the options the API Gateway REST API exposes. Looking back, I've allocated a sizeable portion of that time to understand how one could utilize the mapping templates and the _non-proxy_ integration in the real world. There are a LOT of knobs one could tweak in this type of integration.

![_non-proxy_ integration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mv5lc50xs7xercez05um.jpeg)

- When using the _non-proxy_ integration type, **you have to specify the response mapping template**. If you do not, the API Gateway will fail with _"Internal Server Error"_.

- When writing API Gateway **mapping templates** you **do NOT have the ability to use features that you might have used in [AWS AppSync](https://aws.amazon.com/appsync/) resolver templates**. You should consider the VTL in API Gateway and VTL in AppSync resolvers as two separate entities.

Here is the most minimal AWS CDK code snippet to declare an API Gateway route backed by _non-proxy_ integration I could come up with.

```ts
const api = new aws_apigateway.RestApi(this, "API2", {});

const handler = new aws_lambda_nodejs.NodejsFunction(this, "Handler", {
  entry: join(__dirname, "./handler.ts")
});

const nonProxyIntegrationResource = api.root.addResource("non-proxy");

nonProxyIntegrationResource.addMethod(
  "GET",
  new aws_apigateway.LambdaIntegration(handler, {
    proxy: false,
    /** Optional */
    requestTemplates: {
      /**
       * This is what the Lambda function is invoked with.
       */
      "application/json": '{"foo": "bar"}'
    },
    /**
     * Required
     */
    integrationResponses: [
      {
        statusCode: "200",
        responseTemplates: {
          "application/json": "$input.json('$.body')"
        }
      }
    ]
  }),
  {
    /**
     * Required
     */
    methodResponses: [
      {
        statusCode: "200"
      }
    ]
  }
);
```

## My recommendation

- When integrating API Gateway with AWS Lambda function, **consider using the _proxy_ integration as the default integration type**, especially if you are new to the service or are working with a team yet to familiarize themselves with API Gateway and AWS Lambda.

- Consider using the **_non-proxy_ integration for massaging the input data and precomputing given properties**. Consult with your team on this one. It all depends on the use case.

- **Take some time to learn the _non-proxy_ integration** as the notion of mapping templates and other closely related settings are what drives the API Gateway direct service integrations.

## Closing worlds

I find it very valuable to dive deep into a given AWS service, especially when I'm unfamiliar with a particular way of configuring it – I've mainly used the _proxy_ integration throughout, albeit not that long, my career. I encourage you to do a similar and write about your findings. This way, the whole community can benefit and learn together!

For more serverless content, consider following me on Twitter - [@wm_matuszewski](https://twitter.com/wm_matuszewski)

And as always, thank you for your precious time.