API 网关与具有 URL 编码的 AWS 服务/DDB 集成

问题描述 投票:0回答:1

尝试让 PhoneTrack (https://gitlab.com/eneiluj/phonetrack-android/-/wikis/userdoc) 与我的 API 网关一起接收位置数据。我已经设置了我的 API 来处理发布请求,如果我使用编码

application/jason
来卷曲它,它就可以正常工作。问题是该应用程序正在使用
application/x-www-form-urlencoded
的编码。

我已经设置了两个映射模板,并且尝试了一些组合来使映射工作,但是 x-www-form-urlencoded 模板似乎没有做任何事情,而且我认为我还没有完全理解如何获得这个对吧。

这是我的地形资源:

resource "aws_api_gateway_integration" "ddb_integration" {
  depends_on              = [aws_api_gateway_method.generic_post]
  rest_api_id             = aws_api_gateway_rest_api.generic_api.id
  resource_id             = aws_api_gateway_resource.generic_resource.id
  http_method             = aws_api_gateway_method.generic_post.http_method
  passthrough_behavior    = "NEVER"
  content_handling        = "CONVERT_TO_TEXT"
  integration_http_method = "POST"
  uri                     = "arn:aws:apigateway:${local.workspace.aws_region}:dynamodb:action/PutItem"
  credentials             = aws_iam_role.api_gw_to_ddb.arn
  type                    = "AWS"
  request_templates = {
    "application/json" = <<-EOF
    {
      "TableName": "${aws_dynamodb_table.generic_data.name}",
      "Item": {
        "lon": {
          "N": "$input.json('$.lon')"
        },
        "lat": {
          "N": "$input.json('$.lat')"
        },
        "timestamp": {
          "S": "$input.json('$.timestamp')"
        }
      }
    }
    EOF

    "application/x-www-form-urlencoded" = <<-EOF
    {
      $util.log("Starting processing input body...")
      #foreach( $token in $input.body.split('&') )
          $util.log("Current token: $token")
          
          #set( $keyVal = $token.split('=') )
          #set( $keyValSize = $keyVal.size() )
          $util.log("Split token into key and value. KeyValSize: $keyValSize")
          
          #if( $keyValSize >= 1 && !$keyVal[0].isEmpty() )
              #set( $key = $util.urlDecode($keyVal[0]) )
              $util.log("Decoded key: $key")
              
              #set($key = $key.substring(0,1).toLowerCase() + $key.substring(1))
              $util.log("Processed key with first letter lower-cased: $key")
              
              #if( $keyValSize >= 2 )
                  #set( $val = $util.urlDecode($keyVal[1]) )
                  $util.log("Decoded value: $val")
                  
                  #if( $key == "lon" || $key == "lat" || $key == "timestamp" )
                      $util.log("$key: $val")
                  #end
                  
              #else
                  #set( $val = '' )
                  $util.log("No value found for key. Setting value to empty.")
              #end
              
              "$key": "$util.escapeJavaScript($val)"#if($foreach.hasNext),#end
              
          #else
              $util.log("Error processing token: $token. Either key is missing or empty.")
          #end
      #end
      $util.log("Finished processing input body.")
    }
    EOF
  }
}

这适用于

application/json
版本。我尝试在 Apache Velocity 模板语言中设置的日志记录,模板代码似乎没有登录到 cloudwatch,所以我似乎没有办法研究它是如何工作的。我还尝试使用最简单的版本进行 url 编码:

{
    "TableName": "${aws_dynamodb_table.generic_data.name}",
    "Item": {
      "lon": {
        "N": "$util.urlDecode($input.params('lon'))"
      },
      "lat": {
        "N": "$util.urlDecode($input.params('lat'))"
      },
      "timestamp": {
        "S": "$util.urlDecode($input.params('timestamp'))"
      }
    }
  }

但这也行不通。在我的 APIG 执行日志下面,明显的问题是序列化异常。

问题显然是 URL 编码的对象负载没有被转换成 DDB 可以理解的东西。所以问题是映射模板没有发挥其魔力。这行得通吗?还是我需要使用 lambda 来让它发挥作用?

Apache VTL 似乎对 URL 编码的有效负载没有做任何事情,但是,它似乎对 json 编码的有效负载处理得很好。有没有办法让日志记录功能与 VTL 一起使用?

(REQUEST_ID_REMOVED) Extended Request Id: MGm12FcyoAMEsgA=
(REQUEST_ID_REMOVED) Verifying Usage Plan for request: REQUEST_ID_REMOVED. API Key:  API Stage: STAGE_ID_REMOVED/prod
(REQUEST_ID_REMOVED) API Key  authorized because method 'POST /data' does not require API Key. Request will not contribute to throttle or quota limits
(REQUEST_ID_REMOVED) Usage Plan check succeeded for API Key  and API Stage STAGE_ID_REMOVED/prod
(REQUEST_ID_REMOVED) Starting execution for request: REQUEST_ID_REMOVED
(REQUEST_ID_REMOVED) HTTP Method: POST, Resource Path: /data
(REQUEST_ID_REMOVED) Method request path: {}
(REQUEST_ID_REMOVED) Method request query string: {}
(REQUEST_ID_REMOVED) Method request headers: {User-Agent=curl/8.3.0, X-Forwarded-Proto=https, X-Forwarded-For=REMOVED_IP, content-type=application/x-www-form-urlencoded, Host=REMOVED, X-Forwarded-Port=443, accept=*/*}
(REQUEST_ID_REMOVED) Method request body before transformations: lon=151.0&lat=-33.0&timestamp=1695994041
(REQUEST_ID_REMOVED) Endpoint request URI: https://dynamodb.us-east-1.amazonaws.com/?Action=PutItem
(REQUEST_ID_REMOVED) Endpoint request headers: {Authorization=REMOVED, X-Amz-Date=20231001T034528Z, x-amzn-apigateway-api-id=STAGE_ID_REMOVED, Accept=application/x-www-form-urlencoded, User-Agent=AmazonAPIGateway_STAGE_ID_REMOVED, X-Amz-Security-Token=REMOVED
(REQUEST_ID_REMOVED) Endpoint request body after transformations: lon=151.0&lat=-33.0&timestamp=1695994041
(REQUEST_ID_REMOVED) Sending request to https://dynamodb.us-east-1.amazonaws.com/?Action=PutItem
(REQUEST_ID_REMOVED) Received response. Status: 400, Integration latency: 6 ms
(REQUEST_ID_REMOVED) Endpoint response headers: {Server=Server, Date=Sun, 01 Oct 2023 03:45:28 GMT, Content-Type=application/x-amz-json-1.0, Content-Length=60, Connection=keep-alive, x-amzn-RequestId=REMOVED, x-amz-crc32=REMOVED}
(REQUEST_ID_REMOVED) Endpoint response body before transformations: {"__type": "com.amazon.coral.service#SerializationException"}
(REQUEST_ID_REMOVED) Execution failed due to configuration error: No match for output mapping and no default output mapping configured. Endpoint Response Status Code: 400
(REQUEST_ID_REMOVED) Gateway response type: DEFAULT_5XX with status code: 500
(REQUEST_ID_REMOVED) Gateway response body: {"message": "An unexpected error occurred."}
(REQUEST_ID_REMOVED) Gateway response headers: {x-amzn-ErrorType=InternalServerErrorException}
(REQUEST_ID_REMOVED) Method completed with status: 500

在 GPT 的帮助下,我尝试了许多不同的映射模板组合。我尝试尽可能详细地注销数据,希望能跳出一些内容,但我无法克服这一点。

amazon-web-services amazon-dynamodb aws-api-gateway velocity-template-language
1个回答
0
投票

您收到 400 异常,您尚未为其设置响应映射,因此您不确定错误的真正原因。我的预感是您得到了

ResourceNotFoundException
,并且我相信您在 VTL 中解析表名的方式不正确。获取表名称并将其硬编码到模板中,然后重试。这将让您确定问题的原因,然后您可以着手修复。

还设置一个异常模板,以便您知道遇到的错误。

© www.soinside.com 2019 - 2024. All rights reserved.