How to Build an API Gateway REST API with Lambda Integration

How to Build an API Gateway REST API with Lambda Integration

Build an API Gateway REST API with Lambda Integration

In this tutorial, we’ll walk through setting up a REST API in AWS API Gateway with Lambda Integration, configuring various integration methods and handling method requests and responses.

Introduction

API Gateway Lambda integration allows us to connect our API Gateway resources to Lambda functions and use them as backend logic for our API. There are two types of Lambda integrations:

Lambda Proxy Integration

This approach simplifies development by offloading request parsing and response formatting to API Gateway. This object is then passed to the Lambda function as an event object. The Lambda function processes the event object and returns a JSON response object, which API Gateway further parses and sends back to the client as the API response. This is suitable for most API implementations with JSON input and output formats.

Lambda Non-Proxy Integration

This approach provides greater flexibility and control over the request and response format. The Lambda function parses the request, processes it, and generates the response. This approach provides greater flexibility and control over the request and response format but requires more development effort as the Lambda function needs to handle parsing and formatting.

Implementation

Let’s extend the tutorial by creating a simple CRUD API for managing a list of books.

Step 1: Create an API in API Gateway

In AWS API Gateway, when we create a new API, we have the option to choose between REST API and HTTP API. REST APIs offer more advanced features and capabilities, making them suitable for complex API scenarios. HTTP APIs prioritize simplicity and clarity, making them a perfect fit for streamlined use cases.

Create an API

In the API Gateway console, choose Create API and select REST API. Give it a descriptive name like Book Management API. Select Regional as the desired API endpoint type then click on Create API.

Screenshot-2023-12-12-at-11.58.00-AM-1024x396 How to Build an API Gateway REST API with Lambda Integration

Step 2: Deploy a Lambda function

Next, we need to create Lambda functions to handle the logic for each method. Having a separate Lambda function for each resource method (e.g., Create, Read, Update, Delete) is a common and recommended best practice. This approach follows the Single Responsibility Principle and helps maintain a clean and modular codebase.

Create Function (Create a new book):

import json

def create_book(event, context):
    request_body = json.loads(event['body'])

    # Validate required fields (e.g., title, author, etc.)
    if not request_body.get('title') or not request_body.get('author'):
        return {
            'statusCode': 400,
            'body': json.dumps({'message': 'Title and Author are required.'}),
        }

    new_book = {
        'id': 123,  # Replace with a proper ID generation method
        'title': request_body['title'],
        'author': request_body['author'],
        # Other book details...
    }

    return {
        'statusCode': 201,
        'body': json.dumps(new_book),
    }

Read Function (Create a book by ID):

import json

def get_book(event, context):
    book_id = event['bookId']

    book = {
        "bookId": 123, 
        "bookTitle": "Harry Potter",
        "authorName": "J. K. Rowling"
    }

    if not book_id == "123":
        return {
            'statusCode': 404,
            'body': json.dumps({'message': 'Book not found.'}),
        }

    return {
        'statusCode': 200,
        'body': json.dumps(book),
    }

Step 3: Create Resources and Methods

Next, create resources for the API endpoints, e.g., /books for listing and creating books, and /books/{id} for getting, updating, and deleting individual books. Define appropriate HTTP methods (GET, POST, PUT, DELETE) for each resource.

Screenshot-2023-12-12-at-2.16.56-PM-1024x334 How to Build an API Gateway REST API with Lambda Integration

Step 4: Test the API

API Gateway provides a testing feature called Test for API methods, allowing us to test them before deploying to a stage.

In the API Gateway console, navigate to our API and select the resource/method we want to test. Click on the Test tab. On the test page, we can configure a test event. This is a JSON payload that simulates the input to your API method.

Let’s test the POST request by inputting the request body as below:

Screenshot-2023-12-12-at-3.14.21-PM-1024x729 How to Build an API Gateway REST API with Lambda Integration

Click the Test button to simulate the API request using the configured test event. Review the results, including the request sent and the response received.

Screenshot-2023-12-12-at-3.17.37-PM-1024x766 How to Build an API Gateway REST API with Lambda Integration

The log displays empty values for the method request path, query string, and headers, revealing that no specific details have been extracted from the request yet.

The log indicates that the HTTP POST request is received with a JSON payload. The original request body contains information about the book, including the title and author.

It then transforms this information, prepares an endpoint request to a specified Lambda function, and forwards the request.

Upon receiving the Lambda response, API Gateway performs transformations before sending the final response to the client. This involves mapping the Lambda response to a structured API response.

Step 5: Configure Method and Integration Request/Response

In Amazon API Gateway, both Integration Response and Method Response are components for controlling and defining the structure of API responses. They control how the request and response data is handled at various stages of the API request lifecycle, especially in the context of Lambda Non-Proxy Integration in API Gateway.

Method Request/Response: The Method Request and Response phase captures information from the incoming request and defines the structure of the final API response that is sent to the client.

Integration Request/Response: The Integration Request phase transforms the method request into the format expected by the backend Lambda function. Followed by transforming the Lambda function’s response before sending it back to the client.

To demonstrate this process, let’s consider a URL path /books?id={id} where id is a URL query string, and we want to pass this from the client to our Lambda function. Here’s how we can achieve this:

In the API Gateway console, navigate to our API and select the HTTP GET method. Click on the Method Request tab and click the Edit button.

Under URL Query String Parameters, add a query parameter named id.

Screenshot-2023-12-12-at-3.46.11-PM-916x1024 How to Build an API Gateway REST API with Lambda Integration

Next, open the Integration Request tab and click Edit. Under Mapping Templates, add a new template for application/json (or the appropriate content type). In the template, map the query string parameter to a event body.

Screenshot-2023-12-12-at-3.48.28-PM-797x1024 How to Build an API Gateway REST API with Lambda Integration

For example, if the incoming request has a URL like /books?id=123, this template will transform it into the following JSON structure in the request body:

{
    "id": "123"
}

Now, navigate to the Integration Response tab, edit the integration response for HTTP status code 200, and add a new mapping template to transform the Lambda output to the desired response format.

Screenshot-2023-12-12-at-4.10.37-PM-1022x1024 How to Build an API Gateway REST API with Lambda Integration

Go to the Models section and create a new model call BookResponseModel. Define the model structure as follows:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "BookResponseModel",
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "title": { "type": "string" },
    "author": { "type": "string" }
  },
  "required": ["id", "title", "author"]
}

Go back to the Method Response in the resource. For the 200 HTTP status code, select the BookResponseModel as the response model for application/json.

Screenshot-2023-12-12-at-4.12.49-PM-1024x884 How to Build an API Gateway REST API with Lambda Integration

Test the GET request by inputting the request body as follows:

Screenshot-2023-12-12-at-4.15.51-PM-1024x378 How to Build an API Gateway REST API with Lambda Integration

Click the Test button to simulate the API request using the configured test event. Review the results, including the request sent and the response received.

Screenshot-2023-12-12-at-4.14.02-PM-1024x603 How to Build an API Gateway REST API with Lambda Integration

Step 6: Handle Lambda errors in API Gateway

To handle a 404 not found error, navigate to the Integration Response and update the mapping template as the code snippet below:

#set($inputRoot = $input.path('$'))
#if($inputRoot.statusCode == 404)
    {
        "error": {
            "statusCode": 404,
            "message": "Resource Not Found"
        }
    }
#else
    {
      "id": $util.parseJson($inputRoot.body).bookId,
      "title": $util.parseJson($inputRoot.body).bookTitle,
      "author": $util.parseJson($inputRoot.body).authorName
    }
#end

Click the Test button to simulate the API request using the configured test event. Observe the results, including the request sent and the response received.

Screenshot-2023-12-13-at-8.31.09-AM-1024x422 How to Build an API Gateway REST API with Lambda Integration

Note that the method completed with status: 200. Returning a 200 OK status when a resource is not found can mislead users and make it difficult for them to understand the API’s behavior.

For Lambda custom integrations, you must map errors returned by Lambda in the integration response to standard HTTP error responses for your clients. Otherwise, Lambda errors are returned as 200 OK responses by default and the result is not intuitive for your API users.

https://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html

The Lambda proxy integration requires Lambda to return an output in the following format:

{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}

With Lambda non-proxy integration, to return the desired HTTP status code, rely on integration response to extract the error based on HTTP status regex.

To transform the 404 not found error using integration response, navigate to the Method Response, create a new method response with HTTP code 404. Then, go to the Integration Response tab and create a new integration response:

Screenshot-2023-12-12-at-6.25.58-PM-869x1024 How to Build an API Gateway REST API with Lambda Integration

Our Lambda function should actively raise an exception when it encounters a book not found scenario. When the Lambda function returns an error message, the HTTP status regex will be used to identify the appropriate HTTP status code.

if not book_id == "123":
    raise Exception('Not Found')

Remove the else part of the Mapping Template for the 200 responses:

#set($inputRoot = $input.path('$'))
#if($inputRoot.statusCode == 200)
    {
      "id": $util.parseJson($inputRoot.body).bookId,
      "title": $util.parseJson($inputRoot.body).bookTitle,
      "author": $util.parseJson($inputRoot.body).authorName
    }
#end

Test the API again. We should see the method completed with status: 404, indicating that the resource was not found.

Screenshot-2023-12-13-at-8.41.06-AM-1024x384 How to Build an API Gateway REST API with Lambda Integration

Conclusion

In this tutorial, we’ve covered the process of creating a simple CRUD API for managing a list of books using AWS API Gateway and Lambda functions. By following the steps outlined in this guide, we’ve learned how to set up an API in API Gateway, deploy Lambda functions for handling various CRUD operations, and configure method request/response and integration request/response to shape the behaviour of our API.

Share this content:

Leave a Comment

Discover more from nnyw@tech

Subscribe now to keep reading and get access to the full archive.

Continue reading