I have an API Gateway integration for a method/resource which works when I call it from the API but not when I actually call it:
$ aws apigateway test-invoke-method --rest-api-id $REST_API_ID \
--resource-id $RESOURCE_ID --http-method GET | jq -r .log,.body
This works out fine and I get the following output:
Tue May 16 17:46:42 UTC 2017 : Starting execution for request: test-invoke-request
Tue May 16 17:46:42 UTC 2017 : HTTP Method: GET, Resource Path: /status.json
Tue May 16 17:46:42 UTC 2017 : Method request path: {}
Tue May 16 17:46:42 UTC 2017 : Method request query string: {}
Tue May 16 17:46:42 UTC 2017 : Method request headers: {}
Tue May 16 17:46:42 UTC 2017 : Method request body before transformations:
Tue May 16 17:46:42 UTC 2017 : Endpoint response body before transformations:
Tue May 16 17:46:42 UTC 2017 : Endpoint response headers: {}
Tue May 16 17:46:42 UTC 2017 : Method response body after transformations: { "statusCode": 200 }
Tue May 16 17:46:42 UTC 2017 : Method response headers: {Content-Type=application/json}
Tue May 16 17:46:42 UTC 2017 : Successfully completed execution
Tue May 16 17:46:42 UTC 2017 : Method completed with status: 200
{ "statusCode": 200 }
However, I cannot access this at my URL, which is api.naftuli.wtf/v1/status.json
. I have stages defined at glhf
, stable
, and v1
, so by replacing that, you will see different responses. I just simply want a dummy response that returns a 200 JSON blob.
My Terraform for the resources is here as a Gist. Hopefully this fully shows my API Gateway configuration.
If I test invoke this from the CLI or from the web console, I get back what is expected. However, if I curl this from my deployed API at api.naftuli.wtf, I don't get anything nice:
$ for stage in glhf stable v1 ; do
> url="https://api.naftuli.wtf/${stage}/status.json"
> echo "${url}:"
> curl -i -H 'Content-Type: application/json' \
> https://api.naftuli.wtf/${stage}/status.json
> echo -e '\n
> done
https://api.naftuli.wtf/glhf/status.json:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:38 GMT
x-amzn-RequestId: 712ba52b-3a80-11e7-9fec-b79b62d3bf7f
X-Cache: Error from cloudfront
Via: 1.1 da7a5d0ed7f424609000879e43743066.cloudfront.net (CloudFront)
X-Amz-Cf-Id: hBwlbPCP9n2rlz53I-Qb9KoffHB_FoxUCZUaJYNnU3XhCWuMpQTP1Q==
{"message": "Internal server error"}
https://api.naftuli.wtf/stable/status.json:
HTTP/1.1 403 Forbidden
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:38 GMT
x-amzn-RequestId: 71561066-3a80-11e7-9b00-6700be628328
x-amzn-ErrorType: ForbiddenException
X-Cache: Error from cloudfront
Via: 1.1 0c146399837c7d36c1f0f9d2636f8cf8.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ITX765xD8s4sNuOdXaJ2kPvqPo-w_dsQK3Sq_No130FAHxFuoVhO8w==
{"message":"Forbidden"}
https://api.naftuli.wtf/v1/status.json:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:39 GMT
x-amzn-RequestId: 7185fa99-3a80-11e7-a3b1-2f9e659fc361
X-Cache: Error from cloudfront
Via: 1.1 586f1a150b4ba39f3a668b8055d4d5ea.cloudfront.net (CloudFront)
X-Amz-Cf-Id: dvnOa1s-YlwLSNzBfVyx5tSL6XrjFJM4_fES7MyTofykB3ReU5R1fg==
{"message": "Internal server error"}
My understanding of stages were that they were additional path prefixes to the base path under which all API resources were available. If I had a stage called v1
with a path of /v1
, I'd expect that an API Gateway resource for status.json
will be basically mapped under /v1
, yielding /v1/status.json
.
I may be misunderstanding how API Gateway base path mappings and stages work, but CloudWatch tells me that the call is at least happening, though failing for some obscure reason:
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Verifying Usage Plan for request: c5be3842-6af4-4725-a34f-d6eea8042d17. API Key: API Stage: tcips69qx2/prod_v1
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) API Key authorized because method 'GET /status.json' does not require API Key. Request will not contribute to throttle or quota limits
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Usage Plan check succeeded for API Key and API Stage tcips69qx2/prod_v1
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Starting execution for request: c5be3842-6af4-4725-a34f-d6eea8042d17
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) HTTP Method: GET, Resource Path: /v1/status.json
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Execution failed due to configuration error: statusCode should be an integer which defined in request template
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Method completed with status: 500
Apparently only traffic across the V1 stage is getting through to CloudWatch logs. I have a misconfiguration somewhere and I can't seem to find it.