Connecting the Dots: AWS Lambda Function Meets API Gateway 

October 25, 2023
Get tips and best practices from Develeap’s experts in your inbox

In Part 1 of this series (Deploying AWS Lambda function from scratch), we explored the fundamentals of AWS Lambda, including how to write, package, and deploy Lambda functions using Terraform. If you haven’t read it yet, I recommend starting here to understand the basics.

In this article, we’ll take our serverless journey to the next level by creating an API Gateway and integrating it with our Lambda function. AWS API Gateway allows you to build and manage APIs, making it a powerful tool for exposing your Lambda functions to the world.

In my role as a DevOps Engineer and Head of Partnerships at Develeap, I see a wide range of customer case studies leveraging AWS API Gateway. I have also managed Develeap’s process of obtaining the AWS API Gateway Service Delivery badge, among many others. 

Before we dive into the integration of AWS Lambda with API Gateway, let’s take a moment to understand the core concept of AWS API Gateway.

What is AWS API Gateway?

AWS API Gateway is a fully managed service provided by Amazon Web Services (AWS) that enables you to create, publish, and manage APIs (Application Programming Interfaces) for your applications. Think of it as the gateway or bridge that connects your backend services and functions with the outside world, allowing you to expose your application’s functionalities through HTTP endpoints.

API Gateway serves as the entry point for clients, including web and mobile applications, to interact with your backend services and resources securely and efficiently. It plays a pivotal role in modern application development, enabling you to design, deploy, and monitor APIs with ease.

With AWS API Gateway, you gain several benefits, including:

API Management: API Gateway offers a range of tools for managing your APIs, including versioning, access control, and rate limiting. This ensures that you can control who accesses your APIs and how often.

Security: You can implement authentication and authorization mechanisms to secure your APIs, protecting your data and resources from unauthorized access.

Scalability: API Gateway can handle high levels of traffic and automatically scales to accommodate the demand. This scalability is crucial for ensuring that your APIs perform optimally, even under heavy loads.

Monitoring and Analytics: Gain insights into how your APIs are performing with detailed monitoring and analytics features. This data helps you optimize your APIs and troubleshoot issues effectively.

Integration: Easily integrate your APIs with various AWS services, including AWS Lambda, which allows you to execute code in response to API requests.

We’ll explore how to connect AWS API Gateway with AWS Lambda, creating a powerful combination that enables you to build scalable and responsive serverless applications. Together, they form the backbone of serverless architecture, offering the flexibility, scalability, and cost-effectiveness required for modern application development.

Creating an API Gateway and Integration: 

Part 1 of this series (Deploying AWS Lambda function from scratch) detailed the steps of creating and deploying AWS Lambda using Terraform. Let’s continue on our path to create an API Gateway, connect it to Lambda, and test its functionality using curl. The next step takes us to the next level of our serverless journey.

Step 8: Create an API Gateway

Our journey begins with the creation of an AWS API Gateway. The API Gateway serves as the entry point for our API. It enables us to define routes, methods, and integrations with AWS services such as Lambda.

resource "aws_api_gateway_rest_api" "my_api_gateway" {
  name        = "test-amit-api"
  description = "An example API"
}

Step 9: Create a Resource

In this step, we define a resource within our API Gateway. Resources represent the URL path segments and are essential for structuring your API.

resource "aws_api_gateway_resource" "my_api_resource" {
  rest_api_id = aws_api_gateway_rest_api.my_api_gateway.id
  parent_id   = aws_api_gateway_rest_api.my_api_gateway.root_resource_id
  path_part   = "test"
}

Step 10: Create a Method

Now, we create an HTTP method for our resource. This method defines how clients can interact with the resource. We specify it as a POST method with no authorization.

resource "aws_api_gateway_method" "my_api_method" {
  rest_api_id   = aws_api_gateway_rest_api.my_api_gateway.id
  resource_id   = aws_api_gateway_resource.my_api_resource.id
  http_method   = "POST"
  authorization = "NONE"
}

Step 11: Integration with Lambda

Here comes the magic! We configure the integration between our API Gateway and the Lambda function we deployed earlier. This step ensures that when a client hits our API, it triggers the Lambda function.

resource "aws_api_gateway_integration" "my_api_integration" {
  rest_api_id             = aws_api_gateway_rest_api.my_api_gateway.id
  resource_id             = aws_api_gateway_resource.my_api_resource.id
  http_method             = aws_api_gateway_method.my_api_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.default.invoke_arn
}

Step 12: API Gateway permissions

This code defines an AWS Lambda permission resource for allowing API Gateway to invoke a specific Lambda function. 

resource "aws_lambda_permission" "my_lambda_permission" {
  statement_id  = "AllowMyhelloworldIInvoke"
  action        = "lambda:InvokeFunction"
  function_name = "hello-world-lambda"
  principal     = "apigateway.amazonaws.com"


 # The /* part allows invocation from any stage, method, and resource path
 # within API Gateway.
  source_arn = "${aws_api_gateway_rest_api.my_api_gateway.execution_arn}/*"
}

Step 13: Deployment

Deployments allow us to manage different versions of our API and make them accessible via unique URLs.

resource "aws_api_gateway_deployment" "my_api_deployment" {
  depends_on = [aws_api_gateway_integration.my_api_integration]


  rest_api_id = aws_api_gateway_rest_api.my_api_gateway.id
  stage_name  = "test_stage" 
}

Step 14: Output API Gateway URL

Finally, we define an output that provides the URL of our deployed API Gateway. This URL is where clients can access our API.

output "api_gateway_url" {
  value = aws_api_gateway_deployment.my_api_deployment.invoke_url
}

Run terraform plan:

After initializing your environment, you execute a terraform plan. This command performs a dry run of your Terraform configuration. It analyzes your code and the current state of your infrastructure to determine what changes need to be made to bring your infrastructure in line with your configuration. It provides you with a preview of the changes Terraform intends to apply. This is a crucial step because it helps you understand the impact of your changes before they are applied.

Apply Your Terraform Configuration

Run ‘terraform apply’ to deploy your associated AWS resources. Terraform will handle the deployment process of your Lambda function and API Gateway.

Testing Our Deployed API

Now that we’ve successfully deployed our AWS Lambda function and API Gateway, it’s time to test how they work together. We want to ensure that when clients make requests to our API, it seamlessly triggers the Lambda function and returns the desired response.

To test our deployed API, we will use `curl`, a versatile command-line tool for making HTTP requests.

curl -X POST -H "Content-Type: application/json" -d '{"name":"John"}' <Invoke URL>

Let’s break down the curl command:

  • -X POST: This part of the command specifies that you want to make an HTTP POST request. POST requests are used to send data to a server.
  • -H “Content-Type: application/json”: Here, you’re setting the “Content-Type” header to “application/json.” This header tells the server that the data you’re sending in the request body is in JSON format. It helps the server understand how to interpret the data.
  • -d ‘{“name”:”John”}’: This is where the -d parameter comes into play. It allows you to include data in the request body. In this case, you’re sending a JSON object with a “name” field set to “John” as the data. This data will be sent to the server as part of the POST request.
  • <Invoke URL>: You should replace <Invoke URL> with the actual URL where you want to send this POST request. This is the endpoint where the server will receive the request and process the data you’ve included in the body. Replace `<Invoke URL>` with the actual URL you obtained from the API Gateway deployment outputs. This endpoint will be displayed in the terminal as part of the Terraform output after running `terraform apply`. Simply copy and paste it into your `curl` command.

Send the request!

You should receive a response that matches the expected output from your Lambda function.

curl -X POST -H "Content-Type: application/json" -d '{"name":"John"}' https://andg51u620.execute-api.us-east-1.amazonaws.com/test_stage/test

Expected output:

{"message": "Hello, John!"}

Congratulations! You’ve successfully tested the integration between your AWS Lambda function and API Gateway. You’ve just witnessed how an incoming HTTP request can trigger your Lambda function, which processes the request and generates a response.

Clean-up:

To delete the AWS resources you’ve provisioned using Terraform, you can use the terraform destroy command. This command will remove all the resources defined in your Terraform configuration from AWS, bringing your AWS infrastructure back to its initial state.

Conclusion

By following these steps, you’ve successfully deployed a Lambda function, connected it to API Gateway, and tested its functionality using curl. This integration not only showcases the synergy between Lambda and API Gateway but also demonstrates the effectiveness of Infrastructure as Code (IaC) with Terraform in managing and orchestrating your AWS resources

We’re Hiring!
Develeap is looking for talented DevOps engineers who want to make a difference in the world.