AWS API Gateway 和静态 HTML:“由于配置错误,执行失败:statusCode 应该是请求模板中定义的整数”

Posted

技术标签:

【中文标题】AWS API Gateway 和静态 HTML:“由于配置错误,执行失败:statusCode 应该是请求模板中定义的整数”【英文标题】:AWS API Gateway and static HTML: "Execution failed due to configuration error: statusCode should be an integer which defined in request template" 【发布时间】:2020-05-11 16:27:51 【问题描述】:

我正在尝试使用 AWS API Gateway 提供静态内容。 当我尝试从测试页面和 curl 调用 URL 时,我收到错误:

“由于配置错误导致执行失败:statusCode应该是请求模板中定义的整数”。

这是我在 Terraform 上的配置:

resource "aws_api_gateway_rest_api" "raspberry_api" 
  name        = "raspberry_api"


resource "aws_acm_certificate" "raspberry_alexa_mirko_io" 
  domain_name       = "raspberry.alexa.mirko.io"
  validation_method = "DNS"

  lifecycle 
    create_before_destroy = true
  


resource "aws_route53_record" "raspberry_alexa_mirko_io_cert_validation" 
  name    = aws_acm_certificate.raspberry_alexa_mirko_io.domain_validation_options.0.resource_record_name
  type    = aws_acm_certificate.raspberry_alexa_mirko_io.domain_validation_options.0.resource_record_type
  zone_id = var.route53_zone_id
  records = [aws_acm_certificate.raspberry_alexa_mirko_io.domain_validation_options.0.resource_record_value]
  ttl     = 60


resource "aws_route53_record" "raspberry_alexa_mirko_io" 
  zone_id = var.route53_zone_id
  name = aws_acm_certificate.raspberry_alexa_mirko_io.domain_name
  type = "A"
  alias 
    name = aws_api_gateway_domain_name.raspberry_alexa_mirko_io.cloudfront_domain_name
    zone_id = aws_api_gateway_domain_name.raspberry_alexa_mirko_io.cloudfront_zone_id
    evaluate_target_health = true
  


resource "aws_acm_certificate_validation" "raspberry_alexa_mirko_io" 
  certificate_arn         = aws_acm_certificate.raspberry_alexa_mirko_io.arn
  validation_record_fqdns = [aws_route53_record.raspberry_alexa_mirko_io_cert_validation.fqdn]
  provider = aws.useast1


resource "aws_api_gateway_domain_name" "raspberry_alexa_mirko_io" 
  certificate_arn = aws_acm_certificate_validation.raspberry_alexa_mirko_io.certificate_arn
  domain_name     = aws_acm_certificate.raspberry_alexa_mirko_io.domain_name


resource "aws_api_gateway_base_path_mapping" "raspberry_alexa_mirko_io_base_path_mapping" 
  api_id      = aws_api_gateway_rest_api.raspberry_api.id
  domain_name = aws_api_gateway_domain_name.raspberry_alexa_mirko_io.domain_name


resource "aws_api_gateway_resource" "home" 
  rest_api_id = aws_api_gateway_rest_api.raspberry_api.id
  parent_id   = aws_api_gateway_rest_api.raspberry_api.root_resource_id
  path_part   = "login"


resource "aws_api_gateway_method" "login" 
  rest_api_id   = aws_api_gateway_rest_api.raspberry_api.id
  resource_id   = aws_api_gateway_resource.home.id
  http_method   = "GET"
  authorization = "NONE"


resource "aws_api_gateway_integration" "integration" 
  rest_api_id             = aws_api_gateway_rest_api.raspberry_api.id
  resource_id             = aws_api_gateway_resource.subscribe_raspberry.id
  http_method             = aws_api_gateway_method.subscribe.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.raspberry_lambda.invoke_arn
  # This was just a failed attempt. It did not fix anything
  request_templates = 
    "text/html" = "\"statusCode\": 200"
  


resource "aws_api_gateway_integration" "login_page" 
  rest_api_id          = aws_api_gateway_rest_api.raspberry_api.id
  resource_id          = aws_api_gateway_resource.home.id
  http_method          = aws_api_gateway_method.login.http_method
  type                 = "MOCK"
  timeout_milliseconds = 29000


resource "aws_api_gateway_method_response" "response_200" 
  rest_api_id = aws_api_gateway_rest_api.raspberry_api.id
  resource_id = aws_api_gateway_resource.home.id
  http_method = aws_api_gateway_method.login.http_method
  status_code = "200"


resource "aws_api_gateway_integration_response" "login_page" 
  rest_api_id = aws_api_gateway_rest_api.raspberry_api.id
  resource_id = aws_api_gateway_resource.home.id
  http_method = aws_api_gateway_method.login.http_method
  status_code = aws_api_gateway_method_response.response_200.status_code
  response_templates = 
    "text/html" = data.template_file.login_page.rendered
  


resource "aws_api_gateway_deployment" "example" 
  depends_on = [
    aws_api_gateway_integration.login_page
  ]
  rest_api_id = aws_api_gateway_rest_api.raspberry_api.id
  stage_name  = "production"


我已按照this blog 中的说明进行操作,但没有成功。

【问题讨论】:

一个简单的错字。你输入status_code = "200",这是一个字符串。所需的数据类型是数字,即status_code = 200。事后看来,错误消息试图给你这个提示;-) @SherylHohman 谢谢,我花了几个小时没有成功。真的很感激...... 【参考方案1】:

“200”(带引号)被认为是一个字符串,而不是一个整数

试试status_code = 200(不带引号)

【讨论】:

我这样做了,但仍然收到错误“由于配置错误导致执行失败:statusCode 应该是请求模板中定义的整数”:(【参考方案2】:

只是在这里转发the excellent answer of TheClassic,格式好像是:

request_templates = 
  "application/json" = jsonencode(
    
      statusCode = 200
    
  )

我也遇到了同样的问题,但看起来这可行。

【讨论】:

【参考方案3】:

根据 Bernie 的评论,需要在 aws_api_gateway_integration terraform 资源的 request_templates 属性中明确提供此状态代码。

添加后,我终于得到了 200 个通过 MOCK 端点集成的 OPTIONS。

【讨论】:

【参考方案4】:

我遇到了同样的错误,因为我的代码事先看起来像这样 - 受到 terraform 文档的启发。

resource "aws_api_gateway_integration" "api_gateway" 
  http_method = aws_api_gateway_method.api_gateway.http_method
  resource_id = aws_api_gateway_resource.api_gateway.id
  rest_api_id = aws_api_gateway_rest_api.api_gateway.id
  type        = "MOCK"

阅读此主题后,它现在的工作方式如下:

resource "aws_api_gateway_integration" "api_gateway" 
  http_method = aws_api_gateway_method.api_gateway.http_method
  resource_id = aws_api_gateway_resource.api_gateway.id
  rest_api_id = aws_api_gateway_rest_api.api_gateway.id
  type        = "MOCK"
  request_templates = 
    "application/json" = jsonencode(
      
        statusCode = 200
      
    )
  

【讨论】:

【参考方案5】:

对于可能会看到这一点的其他人,此错误也可能是由于需要验证当您使用 Mock 作为您的集成类型时,您确认您的 RequestTemplates 包含 statusCode 并且 statusCode 的值等于您的 IntegrationResponses 之一/ResponseTemplates/StatusCode

类似:

    requestTemplates: 
      "application/json": "\"statusCode\": 200"
    

【讨论】:

以上是关于AWS API Gateway 和静态 HTML:“由于配置错误,执行失败:statusCode 应该是请求模板中定义的整数”的主要内容,如果未能解决你的问题,请参考以下文章

AWS S3 静态站点 CORS jquery ajax POST 到 API Gateway

如何将 AWS CloudFront 和 API Gateway 并排用于同一个域?

使用 Learner Lab - 使用 S3 静态网页上传图片,搭配 API Gateway 与 Lambda

AWS API Gateway 默认响应和触发 AWS Lambda

AWS Cognito 和 AWS API Gateway 中的用户管理和基于令牌的身份验证

如果在 Terraform 模块中创建了 aws_api_gateway_integration,如何在 aws_api_gateway_deployment 资源上填充depends_on?