【问题标题】:AWS API Gateway Method request path parameter not workingAWS API Gateway 方法请求路径参数不起作用
【发布时间】:2019-09-25 20:38:52
【问题描述】:

我正在尝试配置 API Gateway 以将请求路由到我的后端 GO 微服务上的特定路由。我正在使用GET 请求方法和VPC_LINKNLB 的集成,它路由到我在Fargate 中运行的后端微服务。这是一个简单的REST api,用GO 编写。在服务方面,在我的处理程序中,我为我的舞台路线放置了一个全部响应,然后为/nmapscan 路线放置了一个“Hello World”响应,这就是我想要达到的目标。但是,当我尝试使用调用 url 访问我的后端服务时,尽管请求路径在我的请求响应输出中显示正确,但我仍不断收到捕获所有响应。我是 API Gateway 的新手,我觉得我错过了一些简单的东西。此外,当我在本地运行容器时,我附加了一个 shell 并运行 curl localhost:8000/v1/nmapscan 并得到正确的“Hello World!”回复。以下是响应、我的配置以及来自流日志的响应:

RESPONSE:

user$ curl -v -X GET https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/v1/nmapscan/
> GET /v1/nmapscan/ HTTP/2
> Host: xxxxxxxxxx.execute-api.us-east-1.amazonaws.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< content-type: application/json
< content-length: 27
< date: Wed, 25 Sep 2019 20:24:16 GMT
< x-amzn-requestid: df90f051-dbdd-405f-a708-73668ad955f1
< x-amz-apigw-id: XXXXXXXXXXX=
< x-amzn-trace-id: Root=1-5d8bccf0-44ebf9c5af13c90e1636de42
< x-cache: Miss from cloudfront
< via: 1.1 b7ddb18a56b4bad68ca78b085e9ca451.cloudfront.net (CloudFront)
< x-amz-cf-pop: EWR52-C2
< x-amz-cf-id: lvT1CGlv2fboFJ5AxE917Jr61Nwb4fQOwbranZ3s_vz0EJULhcwudQ==
< 
* Connection #0 to host xxxxxxxxx.execute-api.us-east-1.amazonaws.com left intact
This is the catch all path!

如您所见,这是返回 catch all 响应。它应该返回“Hello World!”。

Configuration:

resource "aws_api_gateway_rest_api" "GOAPI" {
  name        = "GO"
  description = "REST API for GO APIs"
}

resource "aws_api_gateway_resource" "test" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  parent_id   = "${aws_api_gateway_rest_api.GOAPI.root_resource_id}"
  path_part   = "nmapscan"
}

resource "aws_api_gateway_method" "testmethod" {
  rest_api_id   = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id   = "${aws_api_gateway_resource.test.id}"
  http_method   = "GET"
  authorization = "NONE"
  request_parameters = {
    "method.request.path.nmapscan" = true
  }
}

resource "aws_api_gateway_integration" "integrationtest" {
  connection_type = "VPC_LINK"
  connection_id   = "${aws_api_gateway_vpc_link.test.id}"
  type = "HTTP"
  integration_http_method = "GET"
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"
  uri = "${format("http://%s:8000", aws_lb.myapis.dns_name)}"

//  request_parameters = {
//    "integration.request.path.nmapscan" = "method.request.path.nmapscan"
//  }
}


resource "aws_api_gateway_method_response" "test-200" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }
}

resource "aws_api_gateway_integration_response" "testintegrationresponse" {
  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  resource_id = "${aws_api_gateway_resource.test.id}"
  http_method = "${aws_api_gateway_method.testmethod.http_method}"

  status_code = "${aws_api_gateway_method_response.test-200.status_code}"

  response_templates = {
    "application/json" = ""
  }
}

resource "aws_api_gateway_deployment" "testdeploy" {
  depends_on = ["aws_api_gateway_integration.integrationtest"]

  rest_api_id = "${aws_api_gateway_rest_api.GOAPI.id}"
  stage_name = "v1"
}

Flow Logs:

(fdaa14d3-08df-4847-ba63-a9644a65d265) Method request body before transformations:
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request URI: http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request headers: {x-amzn-apigateway-api-id=cqq6k2xrw3, Accept=application/json, User-Agent=AmazonAPIGateway_cqq6k2xrw3, Host=xxx-yyy-zzzzzz.elb.us-east-1.amazonaws.com, X-Amzn-Trace-Id=Root=1-5d8c2eee-51c73680b040aea02ab1dd14}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint request body after transformations:
(fdaa14d3-08df-4847-ba63-a9644a65d265) Sending request to http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000
(fdaa14d3-08df-4847-ba63-a9644a65d265) Received response. Status: 200, Integration latency: 15 ms
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint response headers: {Content-Type=application/json, Date=Thu, 26 Sep 2019 03:22:22 GMT, Content-Length=27}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Endpoint response body before transformations: This is the catch all path!
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method response body after transformations: This is the catch all path!
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method response headers: {X-Amzn-Trace-Id=Root=1-5d8c2eee-51c73680b040aea02ab1dd14, Content-Type=application/json}
(fdaa14d3-08df-4847-ba63-a9644a65d265) Successfully completed execution
(fdaa14d3-08df-4847-ba63-a9644a65d265) Method completed with status: 200

【问题讨论】:

    标签: amazon-web-services rest get aws-api-gateway


    【解决方案1】:

    你的帖子看起来很像this

    如果您确信这不是该回复中提到的内容,那么我会检查您的集成请求中的路由。

    您的 curl 请求的 URI 是 /v1/nmapscan/,这意味着 API Gateway 将查看 STAGE v1,资源 /nmapscan。一旦发生这种情况,API GW 根据集成请求中配置的 uri 将请求发送到 VPC 链接。我对 Terraform 不是很熟悉,但看起来您要将其发送到:

    http://aws_lb.myapis.dns_name:8000

    我还看到您在 terraform 中定义了“请求参数”(但可能被注释掉了?):

    // 请求参数 = { // "integration.request.path.nmapscan" = "method.request.path.nmapscan" // }

    我会在部署后检查 API GW 控制台中的集成请求是否显示它正在路由到正确的路由。在不确定的情况下,我假设您的应用程序路径实际上是 http://aws_lb.myapis.dns_name/nmapscan:8000 并且没有正确传递给 NLB,因为它由于某种原因在集成请求中没有正确映射。

    综上所述,在将请求发送到 NLB 时查看 URI 的最简单方法是启用 API Gateway 执行日志,并在这些日志上启用完整的请求/响应数据。它会给你类似的东西:

    (32e76dc1-2e80-11e9-b849-1d4cbf2f1403) 转换后的端点请求正文:{"resource":"/testproxy","path":"/testproxy","httpMethod":"GET","headers":[TRUNCATED ] (32e76dc1-2e80-11e9-b849-1d4cbf2f1403) 向 [截断] 发送请求

    为了简洁起见,我截断了,但您可以在那里看到路径定义。查看它以缩小错误的来源将很有用。

    【讨论】:

    • 我启用了流日志并使用来自日志的响应更新了我的问题。看起来 URI 设置为 NLB..
    • 有意思,能发一张“集成请求”的UI配置截图吗?当我在 UI 中查看我的时,我看到它具有“端点 URL”字段和“路径参数”字段。如果您的应用程序期望 nmapscan 路由作为路径参数,您希望它显示在后者中,但如果它期望在 URI 路径本身中,那么您应该在 URL 中看到路径。不管怎样,看起来它没有被配置或者 API Gateway 没有根据你的流日志来解释它。
    • 另一个注意事项,API Gateway 使用 SNI 进行 TLS 协商,因此它实际上不会将请求发送到您指定的 URL,它总是将请求发送到 VPC 端点,但它包含一个 Host 标头您在集成响应的“URL”部分中拥有的域,在使用 SNI 以确保 TLS 协商成功时需要该域。所以不要太关注 API 网关将其发送到的 URL。
    • 原来我使用了不正确的 URI。当我将其更改为http://xxx-yyy-zzzzzzz.elb.us-east-1.amazonaws.com:8000/nmapscan 时,我得到了正确的响应。
    猜你喜欢
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    相关资源
    最近更新 更多