Automating CORS using BOTO3 for AWS Api Gateway - amazon-web-services

I have been attempting for the last many hours to configure CORS for the AWS Api Gateway. I have attempted to copy verbatim what the "Enable CORS" button does within the aws console. But even though every method looks identical in the console, POSTing to the rest API works with the "Enable CORS" button but returns a 500 permission error when CORS is set up using my code.
This is the code that is relevant to CORS setup:
# Set the put method response of the POST method
self.apigateway.put_method_response(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='POST',
statusCode='200',
responseParameters={
'method.response.header.Access-Control-Allow-Origin': False
},
responseModels={
'application/json': 'Empty'
}
)
# Set the put integration response of the POST method
self.apigateway.put_integration_response(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='POST',
statusCode='200',
responseParameters={
'method.response.header.Access-Control-Allow-Origin': '\'*\''
},
responseTemplates={
'application/json': ''
}
)
# Add an options method to the rest api
api_method = self.apigateway.put_method(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='OPTIONS',
authorizationType='NONE'
)
# Set the put integration of the OPTIONS method
self.apigateway.put_integration(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='OPTIONS',
type='MOCK',
requestTemplates={
'application/json': ''
}
)
# Set the put method response of the OPTIONS method
self.apigateway.put_method_response(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='OPTIONS',
statusCode='200',
responseParameters={
'method.response.header.Access-Control-Allow-Headers': False,
'method.response.header.Access-Control-Allow-Origin': False,
'method.response.header.Access-Control-Allow-Methods': False
},
responseModels={
'application/json': 'Empty'
}
)
# Set the put integration response of the OPTIONS method
self.apigateway.put_integration_response(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='OPTIONS',
statusCode='200',
responseParameters={
'method.response.header.Access-Control-Allow-Headers': '\'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token\'',
'method.response.header.Access-Control-Allow-Methods': '\'POST,OPTIONS\'',
'method.response.header.Access-Control-Allow-Origin': '\'*\''
},
responseTemplates={
'application/json': ''
}
)
This is the response from get-method for POST and OPTIONS when CORS is enabled through the AWS console:
{
"httpMethod": "POST",
"apiKeyRequired": false,
"methodIntegration": {
"httpMethod": "POST",
"cacheKeyParameters": [],
"integrationResponses": {
"200": {
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"statusCode": "200",
"responseTemplates": {
"application/json": null
}
}
},
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:477869670267:function:controller/invocations",
"requestTemplates": {
"application/json": null
},
"cacheNamespace": "o9h9b8tzo2",
"type": "AWS"
},
"methodResponses": {
"200": {
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": false
},
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
}
}
},
"authorizationType": "NONE"
}
{
"requestParameters": {},
"httpMethod": "OPTIONS",
"methodResponses": {
"200": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": false,
"method.response.header.Access-Control-Allow-Methods": false,
"method.response.header.Access-Control-Allow-Origin": false
},
"responseModels": {
"application/json": "Empty"
}
}
},
"apiKeyRequired": false,
"methodIntegration": {
"cacheNamespace": "o9h9b8tzo2",
"type": "MOCK",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"integrationResponses": {
"200": {
"responseTemplates": {
"application/json": null
},
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"cacheKeyParameters": []
},
"authorizationType": "NONE"
}
And this is the response of get-method from CORS being enabled using my code:
{
"authorizationType": "NONE",
"httpMethod": "POST",
"methodIntegration": {
"requestTemplates": {
"application/json": null
},
"cacheNamespace": "308o168qal",
"uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:477869670267:function:controller/invocations",
"httpMethod": "POST",
"cacheKeyParameters": [],
"integrationResponses": {
"200": {
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"statusCode": "200",
"responseTemplates": {
"application/json": null
}
}
},
"type": "AWS"
},
"apiKeyRequired": false,
"methodResponses": {
"200": {
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": false
},
"responseModels": {
"application/json": "Empty"
},
"statusCode": "200"
}
}
}
{
"authorizationType": "NONE",
"apiKeyRequired": false,
"methodIntegration": {
"integrationResponses": {
"200": {
"statusCode": "200",
"responseTemplates": {
"application/json": null
},
"responseParameters": {
"method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'",
"method.response.header.Access-Control-Allow-Origin": "'*'",
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
}
}
},
"cacheNamespace": "bm4zmvzkdk",
"type": "MOCK",
"cacheKeyParameters": [],
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
}
},
"requestParameters": {},
"methodResponses": {
"200": {
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
},
"responseParameters": {
"method.response.header.Access-Control-Allow-Methods": false,
"method.response.header.Access-Control-Allow-Origin": false,
"method.response.header.Access-Control-Allow-Headers": false
}
}
},
"httpMethod": "OPTIONS"
}
I can not see a single difference, what am I doing wrong?
As per the request of MikeD at AWS the POST request is made from javascript within a file sitting within s3:
function post_request() {
var xhr = new XMLHttpRequest();
var params = JSON.stringify({
request: "registerUser",
user:{
username: document.getElementById("usernameInput").value,
email: document.getElementById("emailInput").value,
password: document.getElementById("passwordInput").value
}
});
xhr.open("POST", "$(endpoint_url)", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.setRequestHeader("x-api-key", "$(api_key)");
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
alert("You are registered!");
}
else{
alert("Could not register. Please try again later.");
}
}
};
xhr.send(params);
return false;
}
Where $(endpoint_url) and $(api_key) are replaced with appropriate values by my setup script (I have confirmed the values are accurate).
This is the verbatim response from the chrome console when the POST request is made:
register.html?X-Amz-Date=20160628T070211Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-…:39 OPTIONS https://dn9sjxz0i9.execute-api.us-east-1.amazonaws.com/prod post_request # register.html?X-Amz-Date=20160628T070211Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-…:39document.getElementById.onsubmit # register.html?X-Amz-Date=20160628T070211Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-…:44
register.html?X-Amz-Date=20160628T070211Z&X-Amz-Expires=300&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-…:1 XMLHttpRequest cannot load https://dn9sjxz0i9.execute-api.us-east-1.amazonaws.com/prod. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://s3.amazonaws.com' is therefore not allowed access. The response had HTTP status code 500.

The put integration of the OPTIONS method needs to have a mapping template which includes a statusCode with a 200 value. It looks like your code was setting the mapping template to an empty string (''). When you create the integration via the API Gateway, it adds a default mapping template of: {"statusCode": 200}
Add the same mapping template to your put integration like so:
# Set the put integration of the OPTIONS method
self.apigateway.put_integration(
restApiId=self.rest_api['id'],
resourceId=root_resource['id'],
httpMethod='OPTIONS',
type='MOCK',
requestTemplates={
'application/json': '{"statusCode": 200}'
}
)

Related

Can we use GET method in api-gateway to invoke step function?

I am invoking step function from api-gateway. For POST request it is working fine. Can I use GET request as well? as we we have to pass state-machine ARN in body or mapping template. Is there any work around?
Below is my cloud formation template:
"paths": {
"/individual": {
"get": {
"operationId": "GET HTTP",
"responses": {
"200": {
"description": "200 response"
}
},
"x-amazon-apigateway-integration": {
"type": "AWS",
"httpMethod": "GET",
"uri": "arn:aws:apigateway:eu-west-1:states:action/StartExecution",
"credentials": {
"Fn::GetAtt": [
"apiGatewayIamRoleGet",
"Arn"
]
},
"requestTemplates": {
"application/json": {
"Fn::Sub": [
"#set($body= $input.json('$'))\n #set($inputRoot='{ \"inputData\" :'+$body+',\"apiInfo\":{\"httpMethod\" :\"'+ $context.httpMethod+'\",\"apiKey\" :\"'+ $context.identity.apiKey+'\"}}')\n #set($apiData=$util.escapeJavaScript($inputRoot))\n #set($apiData=$apiData.replaceAll(\"\\'\",\"'\"))\n {\n \"input\" :\"$apiData\",\n \"stateMachineArn\": \"${StepFunctionArn}\" \n }",
{
"StepFunctionArn": {
"Ref": "StepFunctionGet"
}
}
]
}
},
"payloadFormatVersion": 1.0,
"responses": {
"default": {
"statusCode": "200"
}
}
}
}
}
}
I have sorted out the issue. httpMethod in api-gateway integration needs to be POST I used GET there which causing error.

API Gateway - Return XML or JSON

I have a node API Gateway stack and a Node Lambda. I've been trying to get API gateway to return content-type: application/xml OR application/json depending on the request (returnType=xml or returnType=json).
I have tried adding response models and that didn't work. BinaryTypes didn't work either. I have gotten it to do either application/json OR application/xml but I can't get it to do both. Is what I'm trying to do even possible? or should I create two separate endpoints?
This example always returns application/json.
Here is my lambda:
exports.handler = async function (event, context, callback) {
var format = event.format;
if (!format) {
callback(Error("[BadRequest] missing parameters"));
}
const promise = new Promise(function (resolve, reject) {
https
.get("exampleendpoint.com", (res) => {
let body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
var results = JSON.parse(body);
if (format && format.toUpperCase() === "XML") {
var response = {
statusCode: 200,
headers: { "content-type": "application/xml" },
body:
'<?xml version="1.0" encoding="UTF-8"?><result>' +
OBJtoXML(results) +
"</result>",
};
resolve(response);
} else {
var response = {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify(results),
};
resolve(response);
}
});
})
.on("error", (e) => {
var response = {
statusCode: 500,
body: "",
errorMessage: "Error from example.com",
};
resolve(response);
});
});
return promise;
};
Here is my api gateway code:
const epqApi = new gateway.RestApi(this, "restApi", {
restApiName: "resultsApi",
cloudWatchRole: true,
description: "Calls the service for the app",
endpointTypes: [gateway.EndpointType.REGIONAL],
deployOptions: {
stageName: "prod",
loggingLevel: gateway.MethodLoggingLevel.OFF,
dataTraceEnabled: false,
},
});
const epqResource = epqApi.root.addResource("v1");
const epqIntegration: gateway.LambdaIntegration =
new gateway.LambdaIntegration(generatePqsResultFunction, {
proxy: false,
allowTestInvoke: true,
passthroughBehavior: gateway.PassthroughBehavior.NEVER,
contentHandling: gateway.ContentHandling.CONVERT_TO_TEXT,
requestTemplates: {
"application/json": `{
"format":"$input.params(\'format\')"
}`,
},
integrationResponses: [
{
statusCode: "200",
responseParameters: {
"method.response.header.Access-Control-Allow-Origin": "'*'",
},
responseTemplates: {
"application/json": "$input.path('$.body')",
"application/xml": "$input.path('$.body')",
},
},
{
statusCode: "400",
selectionPattern: "^\\[BadRequest\\].*",
responseParameters: {
"method.response.header.Access-Control-Allow-Origin": "'*'",
},
responseTemplates: {
"application/javascript":
"#set($inputRoot = $input.path('$')) {\"errorMessage\" : \"$input.path('$.errorMessage')\"}",
},
},
],
});
epqResource.addMethod("GET", epqIntegration, {
requestParameters: {
//all params need to be in here, even if they are not required
"method.request.querystring.x": false,
"method.request.querystring.y": false,
"method.request.querystring.units": false,
"method.request.querystring.format": false,
"method.request.querystring.wkid": false,
"method.request.querystring.includeDate": false,
},
methodResponses: [
// Successful response from the integration
{
statusCode: "200",
responseParameters: {
"method.response.header.Access-Control-Allow-Origin": true,
},
},
{
statusCode: "400",
responseParameters: {
"method.response.header.Access-Control-Allow-Origin": true,
},
},
],
});
}

How to validate application/x-www-form-urlencoded request using AWS API Gateway model scema and(or) mapping template

I am sending request to API Gateway from Slack. The request is then sent to lambda to process it. I would like to filter out invalid requests before hitting lambda, at the API Gateway level itself. The "entire" payload sent by slack is like below;
{
resource: '/',
path: '/',
httpMethod: 'POST',
headers: {
Accept: 'application/json,*/*',
'Accept-Encoding': 'gzip,deflate',
'Content-Type': 'application/x-www-form-urlencoded',
Host: 'qweehhy6xd.execute-api.us-east-1.amazonaws.com',
'User-Agent': 'Slackbot 1.0 (+https://api.slack.com/robots)',
'X-Amzn-Trace-Id': 'Root=1-6204af65-03e4d5b23ec5f79e0ehgfdc',
'X-Forwarded-For': '133.237.255.123',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https',
'X-Slack-Request-Timestamp': '1644474213',
'X-Slack-Signature': 'v0=c56tghyt30c8a8ec9228a73d3849de4de9055164a3d72a1793786f8d04617ecd7'
},
multiValueHeaders: {
Accept: [ 'application/json,*/*' ],
'Accept-Encoding': [ 'gzip,deflate' ],
'Content-Type': [ 'application/x-www-form-urlencoded' ],
Host: [ 'qweehhy6xd.execute-api.us-east-1.amazonaws.com' ],
'User-Agent': [ 'Slackbot 1.0 (+https://api.slack.com/robots)' ],
'X-Amzn-Trace-Id': [ 'Root=1-6204af65-03e4d5b87ec5f79e0ee0c632' ],
'X-Forwarded-For': [ '133.237.255.123' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ],
'X-Slack-Request-Timestamp': [ '1644474213' ],
'X-Slack-Signature': [
'v0=c56tghyt30c8a8ec9228a73d3849de4de9055164a3d72a1793786f8d04617ecd7'
]
},
queryStringParameters: null,
multiValueQueryStringParameters: null,
pathParameters: null,
stageVariables: null,
requestContext: {
resourceId: 's7q8swr5fr',
resourcePath: '/',
httpMethod: 'POST',
extendedRequestId: 'SPYX4GyfIAMFX2A=',
requestTime: '10/Feb/2022:06:23:33 +0000',
path: '/qwerty',
accountId: '592976962544',
protocol: 'HTTP/1.1',
stage: 'qwerty',
domainPrefix: 'qweehhy6xd',
requestTimeEpoch: 1644474213489,
requestId: 'vtg02b44-a456-4gt0-abe4-499146d32b5b',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: '133.237.255.123',
principalOrgId: null,
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'Slackbot 1.0 (+https://api.slack.com/robots)',
user: null
},
domainName: 'qweehhy6xd.execute-api.us-east-1.amazonaws.com',
apiId: 'qweehhy6xd'
},
body: 'parama=valuea&paramb=value_b&param_c=valuec',
isBase64Encoded: false
}
Now, I would like to validate this string at the API Gateway level. Say, requestContext.resourceId is s7q8swr5fr in the request payload. I would like to terminate all requests where resourceId is not s7q8swr5fr. Something to note here is Content-Type is application/x-www-form-urlencoded.
Somebody please tell me how to achieve this?
Thank you.
EDIT
I used the model below;
{
"$schema": "http://json-schema.org/draft-04/schema# ",
"title": "TestModel",
"type": "object",
"properties": {
"requestContext": {
"type": "object",
"required": ["resourceId", "accountId", "domainPrefix"],
"properties": {
"resourceId": { "type": "string", "pattern": "s7q8swr5fr" },
"accountId": { "type": "string", "pattern": "592976962544" },
"domainPrefix": { "type": "string", "pattern": "qweehhy6xd" }
}
}
}
}
The model is then saved and mentioned under the method request configuration, like below;

How to test a GET and POST call from inside of Lambda

I am learning Lambda, have created a Cloud Watch Metrics which triggers Lambda every one minute. At present, my Lambda function is executing properly. But I want to make a fake GET and POST call from inside of Lambda. Something like below:
var https = require('https');
exports.handler = (event, context, callback) => {
var params = {
host: "example.com",
path: "/api/v1/yourmethod"
};
var req = https.request(params, function(res) {
let data = '';
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
console.log("DONE");
console.log(JSON.parse(data));
});
});
req.end();
};
Question - Since I don't have any GET and POST endpoint/Code hosted in AWS is there any way I can test whether my GET call and POST call from inside of Lambda is working fine? Is there any way in AWS to put together a fake endpoint or something in AWS and make REST call to it for testing purposes?
You can use JSONPlaceholder's APIs for testing calls to external APIs,
They have released Fake Online REST APIs for Testing and Prototyping
You can test calling different http method calls like GET, PUT, POST, DELETE
https://jsonplaceholder.typicode.com/
In case you are using Lambda proxy integration Event will contents a lot of additional information about request: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
{
"message": "Hello me!",
"input": {
"resource": "/{proxy+}",
"path": "/hello/world",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"cache-control": "no-cache",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Content-Type": "application/json",
"headerName": "headerValue",
"Host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
"Postman-Token": "9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f",
"User-Agent": "PostmanRuntime/2.4.5",
"Via": "1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A==",
"X-Forwarded-For": "54.240.196.186, 54.182.214.83",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders":{
'Accept':[
"*/*"
],
'Accept-Encoding':[
"gzip, deflate"
],
'cache-control':[
"no-cache"
],
'CloudFront-Forwarded-Proto':[
"https"
],
'CloudFront-Is-Desktop-Viewer':[
"true"
],
'CloudFront-Is-Mobile-Viewer':[
"false"
],
'CloudFront-Is-SmartTV-Viewer':[
"false"
],
'CloudFront-Is-Tablet-Viewer':[
"false"
],
'CloudFront-Viewer-Country':[
"US"
],
'':[
""
],
'Content-Type':[
"application/json"
],
'headerName':[
"headerValue"
],
'Host':[
"gy415nuibc.execute-api.us-east-1.amazonaws.com"
],
'Postman-Token':[
"9f583ef0-ed83-4a38-aef3-eb9ce3f7a57f"
],
'User-Agent':[
"PostmanRuntime/2.4.5"
],
'Via':[
"1.1 d98420743a69852491bbdea73f7680bd.cloudfront.net (CloudFront)"
],
'X-Amz-Cf-Id':[
"pn-PWIJc6thYnZm5P0NMgOUglL1DYtl0gdeJky8tqsg8iS_sgsKD1A=="
],
'X-Forwarded-For':[
"54.240.196.186, 54.182.214.83"
],
'X-Forwarded-Port':[
"443"
],
'X-Forwarded-Proto':[
"https"
]
},
"queryStringParameters": {
"name": "me",
"multivalueName": "me"
},
"multiValueQueryStringParameters":{
"name":[
"me"
],
"multivalueName":[
"you",
"me"
]
},
"pathParameters": {
"proxy": "hello/world"
},
"stageVariables": {
"stageVariableName": "stageVariableValue"
},
"requestContext": {
"accountId": "12345678912",
"resourceId": "roq9wj",
"stage": "testStage",
"requestId": "deef4878-7910-11e6-8f14-25afc3e9ae33",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": null,
"sourceIp": "192.168.196.186",
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "PostmanRuntime/2.4.5",
"user": null
},
"resourcePath": "/{proxy+}",
"httpMethod": "POST",
"apiId": "gy415nuibc"
},
"body": "{\r\n\t\"a\": 1\r\n}",
"isBase64Encoded": false
}
}

AWS Mysfits - Invalid HTTP Endpoint API Gateway Push

On Module 4 of the AWS Mythical Mysfits tutorial and I am unable to push the API changes after updating the swagger doc with all of the replace mes. I have followed the instructions for this section three times.
REF: https://aws.amazon.com/getting-started/projects/build-modern-app-fargate-lambda-dynamodb-python/module-four/
I am running the following command through Cloud9:
aws apigateway import-rest-api --parameters endpointConfigurationTypes=REGIONAL --body file://~/environment/aws-modern-application-workshop/module-4/aws-cli/api-swagger.json --fail-on-warnings
With the api-swagger-json:
{
"swagger": 2.0,
"info": {
"title": "MysfitsApi"
},
"securityDefinitions": {
"MysfitsUserPoolAuthorizer": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
"x-amazon-apigateway-authtype": "cognito_user_pools",
"x-amazon-apigateway-authorizer": {
"type": "COGNITO_USER_POOLS",
"providerARNs": [
"arn:aws:cognito-idp:us-east-2:730082756200:userpool/us-east-2_jFYjOTZRU"
]
}
}
},
"paths": {
"/": {
"get": {
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
},
"x-amazon-apigateway-integration": {
"connectionType": "VPC_LINK",
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"connectionId": "wg0305",
"httpMethod": "GET",
"type": "HTTP_PROXY",
"uri": "mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com"
}
},
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
},
"/mysfits": {
"get": {
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
},
"x-amazon-apigateway-integration": {
"connectionType": "VPC_LINK",
"connectionId": "wg0305",
"httpMethod": "GET",
"type": "HTTP_PROXY",
"uri": "http://mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com/mysfits",
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
}
}
},
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
},
"/mysfits/{mysfitId}": {
"get": {
"parameters": [{
"name": "mysfitId",
"in": "path",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
},
"x-amazon-apigateway-integration": {
"requestParameters": {
"integration.request.path.mysfitId": "method.request.path.mysfitId"
},
"connectionType": "VPC_LINK",
"connectionId": "wg0305",
"httpMethod": "GET",
"type": "HTTP_PROXY",
"uri": "http://mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com/mysfits/{mysfitId}",
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
}
}
},
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
},
"/mysfits/{mysfitId}/adopt": {
"post": {
"parameters": [{
"name": "mysfitId",
"in": "path",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
},
"security": [{
"MysfitsUserPoolAuthorizer": [
]
}],
"x-amazon-apigateway-integration": {
"requestParameters": {
"integration.request.path.mysfitId": "method.request.path.mysfitId"
},
"connectionType": "VPC_LINK",
"connectionId": "wg0305",
"httpMethod": "POST",
"type": "HTTP_PROXY",
"uri": "http://mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com/mysfits/{mysfitId}/adopt",
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
}
}
},
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
},
"/mysfits/{mysfitId}/like": {
"post": {
"parameters": [{
"name": "mysfitId",
"in": "path",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
},
"security": [{
"MysfitsUserPoolAuthorizer": [
]
}],
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"requestParameters": {
"integration.request.path.mysfitId": "method.request.path.mysfitId"
},
"connectionType": "VPC_LINK",
"connectionId": "wg0305",
"httpMethod": "POST",
"security": [{
"MysfitsUserPoolAuthorizer": [
]
}],
"type": "HTTP_PROXY",
"uri": "http://mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com/mysfits/{mysfitId}/like",
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
}
}
},
"options": {
"summary": "CORS support",
"description": "Enable CORS by returning correct headers\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"CORS"
],
"x-amazon-apigateway-integration": {
"type": "mock",
"requestTemplates": {
"application/json": "{\n \"statusCode\" : 200\n}\n"
},
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Methods": "'*'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"responseTemplates": {
"application/json": "{}\n"
}
}
}
},
"responses": {
"200": {
"description": "Default response for CORS method",
"headers": {
"Access-Control-Allow-Headers": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Origin": {
"type": "string"
}
}
}
}
}
}
}
}
I receive the error:
An error occurred (BadRequestException) when calling the ImportRestApi operation: Errors found during import:
Unable to put integration on 'GET' for resource at path '/': Invalid HTTP endpoint specified for URI
Where am I going wrong? Which URI is invalid? How can I add more error catching to see the line where it ran into this exception and the exception message?
Because your swagger file is malformed. It is giving an error "duplicated mapping key" when validated. I think you have defined the "responses" twice.
I had the same issue. Quite simply, URI in '/' should be http://mysfits-nlb-52741b4979bb0b50.elb.us-east-2.amazonaws.com