I am trying to create a REST API with 2 methods GET and POST. Here is the work I have done:
The problem: After the deployment, it worked as expected (200) when I tried to hit POST. However, GET is giving a 500 error. This is what I see on the AWS console.
Why is it that POST is working and GET is throwing an error? Any leads to rectifying this error or providing some explanation are appreciated.
Below is my Terraform configuration.
Note: I included only the "aws_api_gateway_*" resources. IAM roles, Lambdas, Lambda permissions are all good.
# Lambda handler - This is the same for both GET and POST. I used the same in both lambdas integrated to GET and POST.
import json
def lambda_handler(event, context):
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps("Hello World")
}
################################################################################
# REST API and Resource
################################################################################
resource "aws_api_gateway_rest_api" "hello_world_v1" {
name = "hello_world_v1"
}
resource "aws_api_gateway_resource" "hello_world_v1" {
parent_id = aws_api_gateway_rest_api.hello_world_v1.root_resource_id
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
path_part = "test"
}
################################################################################
# GET - method and integration
################################################################################
resource "aws_api_gateway_method" "hello_world_v1_get" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
resource_id = aws_api_gateway_resource.hello_world_v1.id
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "hello_world_v1_get" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
resource_id = aws_api_gateway_method.hello_world_v1_get.resource_id
http_method = aws_api_gateway_method.hello_world_v1_get.http_method
integration_http_method = "GET"
type = "AWS_PROXY"
uri = aws_lambda_function.lambda_hello_world_v1_get.invoke_arn
# I initially didn't use this request template.
# I tried this after reading it somewhere while I was attempting to search for a solution.
# However,using or not using, didn't work out.
request_templates = {
"application/json" = jsonencode(
{
statusCode = 200
}
)
}
}
################################################################################
# POST - method and integration
################################################################################
resource "aws_api_gateway_method" "hello_world_v1_post" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
resource_id = aws_api_gateway_resource.hello_world_v1.id
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "hello_world_v1_post" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
resource_id = aws_api_gateway_method.hello_world_v1_post.resource_id
http_method = aws_api_gateway_method.hello_world_v1_post.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.lambda_hello_world_v1_post.invoke_arn
}
################################################################################
# Stage and Deployment
################################################################################
resource "aws_api_gateway_deployment" "hello_world_v1" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
depends_on = [
aws_api_gateway_method.hello_world_v1_get,
aws_api_gateway_method.hello_world_v1_post
]
}
resource "aws_api_gateway_stage" "hello_world_v1" {
deployment_id = aws_api_gateway_deployment.hello_world_v1.id
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
stage_name = "development"
}
According to the documentation:
integration_http_method - (Optional) The integration HTTP method (GET, POST, PUT, DELETE, HEAD, OPTIONs, ANY, PATCH) specifying how API Gateway will interact with the back end. Required if type is AWS, AWS_PROXY, HTTP or HTTP_PROXY. Not all methods are compatible with all AWS integrations. e.g., Lambda function can only be invoked via POST.
In a very simple way, the http_method
attribute refers to the HTTP Method of your endpoint, the integration_http_method
is the HTTP method of the call that API Gateway will do to invoke the Lambda function.
Just change it to POST:
resource "aws_api_gateway_integration" "hello_world_v1_get" {
rest_api_id = aws_api_gateway_rest_api.hello_world_v1.id
resource_id = aws_api_gateway_method.hello_world_v1_get.resource_id
http_method = aws_api_gateway_method.hello_world_v1_get.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.lambda_hello_world_v1_get.invoke_arn
# I initially didn't use this request template.
# I tried this after reading it somewhere while I was attempting to search for a solution.
# However,using or not using, didn't work out.
request_templates = {
"application/json" = jsonencode(
{
statusCode = 200
}
)
}
}