AWS Mysfits - Invalid HTTP Endpoint API Gateway Push - amazon-web-services

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

Related

How to enable API Gateway endpoint Authorization flag to use AWS Cognito user pool - using Terraform

I am trying to enable the Authorization Flag and Enable OAuth scope directly from API JSON definition deployed through Terraform. Although I am able to attach Cognito to the API Gateway as the Authorizer but not able to enable the endpoints with it using terraform (Please see the attached screenshot).
#Screenshot
Here's the attached code for API Gateway:
#Create API Gateway
resource "aws_api_gateway_rest_api" "manidemoapi" {
name = "manidemoapi"
body = <<EOF
{
"openapi": "3.0.1",
"info": {
"title": "Example Pet Store",
"description": "A Pet Store API.",
"version": "1.0"
},
"paths": {
"/pets": {
"get": {
"operationId": "GET HTTP",
"parameters": [
{
"name": "type",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "page",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "200 response",
"headers": {
"Access-Control-Allow-Origin": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pets"
}
}
}
}
},
"x-amazon-apigateway-integration": {
"type": "HTTP_PROXY",
"httpMethod": "GET",
"uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets",
"payloadFormatVersion": 1.0
}
},
"post": {
"operationId": "Create Pet",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPet"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "200 response",
"headers": {
"Access-Control-Allow-Origin": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPetResponse"
}
}
}
}
},
"x-amazon-apigateway-integration": {
"type": "HTTP_PROXY",
"httpMethod": "POST",
"uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets",
"payloadFormatVersion": 1.0
}
}
},
"/pets/{petId}": {
"get": {
"operationId": "Get Pet",
"parameters": [
{
"name": "petId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "200 response",
"headers": {
"Access-Control-Allow-Origin": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
}
}
}
},
"x-amazon-apigateway-integration": {
"type": "HTTP_PROXY",
"httpMethod": "GET",
"uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets/{petId}",
"payloadFormatVersion": 1.0
}
}
}
},
"x-amazon-apigateway-cors": {
"allowOrigins": [
"*"
],
"security" : [ {
"manicognito-authorizer" : [ "get_details" ]
} ],
"allowMethods": [
"GET",
"OPTIONS",
"POST"
],
"allowHeaders": [
"x-amzm-header",
"x-apigateway-header",
"x-api-key",
"authorization",
"x-amz-date",
"content-type"
]
},
"components": {
"securitySchemes" : {
"manicognito-authorizer" : {
"type" : "apiKey",
"name" : "Authorization",
"in" : "header",
"x-amazon-apigateway-authtype" : "cognito_user_pools"
}
},
"schemas": {
"Pets": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Pet"
}
},
"Empty": {
"type": "object"
},
"NewPetResponse": {
"type": "object",
"properties": {
"pet": {
"$ref": "#/components/schemas/Pet"
},
"message": {
"type": "string"
}
}
},
"Pet": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"price": {
"type": "number"
}
}
},
"NewPet": {
"type": "object",
"properties": {
"type": {
"$ref": "#/components/schemas/PetType"
},
"price": {
"type": "number"
}
}
},
"PetType": {
"type": "string",
"enum": [
"dog",
"cat",
"fish",
"bird",
"gecko"
]
}
}
}
}
EOF
endpoint_configuration {
types = ["REGIONAL"]
}
}
#Deploy API Gateway
resource "aws_api_gateway_deployment" "manidemoapi" {
rest_api_id = aws_api_gateway_rest_api.manidemoapi.id
triggers = {
redeployment = sha1(jsonencode(aws_api_gateway_rest_api.manidemoapi.body))
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "manidemoapi" {
deployment_id = aws_api_gateway_deployment.manidemoapi.id
rest_api_id = aws_api_gateway_rest_api.manidemoapi.id
stage_name = "manidemoapi-dev"
}
resource "aws_api_gateway_authorizer" "manidemoapi" {
name = "manicognito-authorizer"
type = "COGNITO_USER_POOLS"
rest_api_id = aws_api_gateway_rest_api.manidemoapi.id
provider_arns = [aws_cognito_user_pool.pool.arn]
}
The root problem is that authorization is "method-scoped", i.e. you have to specify the authorizer for each API method. You should add a terraform resource "aws_api_gateway_method" as the following:
resource "aws_api_gateway_method" "default" {
http_method = <http-method>
authorization = "COGNITO_USER_POOLS"
authorizer_id = <your-authorizer-id>
resource_id = <resource-id>
rest_api_id = <rest-api-id>
}
However, since you are using OpenAPI Specification approach rather than Terraform resource approach to define Terraform, you may need to consider to transform your template to the latter approach.

API gateway - message "select an integration response." when creating stack using cloudformation

This is what I am expecting to see in API Gateway after creating the stack.
But this is what's actually happen.
In the method response, it shows message "select an integration response.", but
I did add the model in the method response, and "HTTP status: Proxy" should be shown
What's going on?
resources.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"HelloWorldApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "hello-api",
"Description": "API used for practice",
"FailOnWarnings": true
}
},
"getBannerMethod": {
"Type": "AWS::ApiGateway::Method",
"DependsOn": ["HelloWorldApi"],
"Properties": {
"RestApiId": {
"Ref": "HelloWorldApi"
},
"ResourceId": {
"Ref": "BannerResource"
},
"HttpMethod": "GET",
"MethodResponses":[
{
"ResponseModels" : {"application/json" : "Empty"},
"ResponseParameters":{
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"StatusCode" : "200"
},
{
"StatusCode": "500"
}
],
"AuthorizationType": "NONE",
"Integration": {
"Credentials": {
"Fn::ImportValue": {
"Fn::Sub": "${RolesStack}-ApiGatewayRoleArn"
}
},
"IntegrationHttpMethod": "POST",
"Type": "AWS_PROXY",
"Uri": {
"Fn::Join": ["",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": ["getBannerHandler", "Arn"]
},
"/invocations"
]
]
}
}
}
}
}
}
Just add this inside Integration :
"IntegrationResponses": [{
"ResponseParameters":{
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"StatusCode" : "200"
}]
This below block
"MethodResponses":[
{
"ResponseModels" : {"application/json" : "Empty"},
"ResponseParameters":{
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"StatusCode" : "200"
},
{
"StatusCode": "500"
}
],
is set for method response level. You are looking at lambda means integration response level. For that you have to set IntegrationResponses.
Full template :
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"HelloWorldApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "hello-api",
"Description": "API used for practice",
"FailOnWarnings": true
}
},
"getBannerMethod": {
"Type": "AWS::ApiGateway::Method",
"DependsOn": ["HelloWorldApi"],
"Properties": {
"RestApiId": {
"Ref": "HelloWorldApi"
},
"ResourceId": {
"Ref": "BannerResource"
},
"HttpMethod": "GET",
"MethodResponses":[
{
"ResponseModels" : {"application/json" : "Empty"},
"ResponseParameters":{
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"StatusCode" : "200"
},
{
"StatusCode": "500"
}
],
"AuthorizationType": "NONE",
"Integration": {
"Credentials": {
"Fn::ImportValue": {
"Fn::Sub": "${RolesStack}-ApiGatewayRoleArn"
}
},
"IntegrationHttpMethod": "POST",
"IntegrationResponses": [{
"ResponseParameters":{
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
"StatusCode" : "200"
}],
"Type": "AWS_PROXY",
"Uri": {
"Fn::Join": ["",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": ["getBannerHandler", "Arn"]
},
"/invocations"
]
]
}
}
}
}
}
}
For those looking for the quick hack workaround to get it working from the console (like me).
I found the answer here: https://github.com/hashicorp/terraform-provider-aws/issues/11561
The only way to fix this issue is to login to the AWS Console and the do the following:
Go to "Integration request" and then uncheck "Use Lambda Proxy integration" and then check it again.
After performing the above steps the Method response correctly shows the mapped model.

How to enable CORS configuration in WSO2 for a specific API by using REST API?

I am creating and publishing APIs using WSO2 REST APIs and not from its UI because i have hundreds of WSO2 APIs to manage. I use swagger file(in json format) to configure all the details about my API and then publish this swagger file using curl command. I want to enable CORS configuration for my WSO2 APIs.
The documentation provided for WSO2 APIs provides information only about enabling CORS config via UI. Here is the link.
I could not find any info as to how i can enable it by any means other than directly from its UI. I have tried adding the following field in the API's swagger file but this change is not reflected in the published API.
"CORSConfiguration": {
"Enabled": "true",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
"Access-Control-Allow-Headers": "authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction",
"Access-Control-Allow-Credentials": "false"
}
Any help to enable the CORS configuration for a particular API will be appreciated. Thanks :)
CORS information should go in the API create/update payload like this.
"corsConfiguration": {
"accessControlAllowOrigins": ["*"],
"accessControlAllowHeaders": [
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": false,
"corsConfigurationEnabled": false
}
See the sample payload in [1].
[1] https://docs.wso2.com/display/AM260/apidocs/publisher/#!/operations#APIIndividual#apisPost
#Bee, here is what i tried to do.
{
"swagger": "2.0",
"info": {
"description": "Registration Type Master",
"version": "1.0",
"title": "Test_Entity_Master_API",
"termsOfService": "urn:tos",
"contact": {"name":"RD"},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0"
}
},
"host": "http://sampleurl.com/",
"basePath": "/samplemethod",
"schemes": [
"http"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/regtype/createregtype": {
"post": {
"summary": "Create reg type entry",
"tags": [
"Registration Type Master"
],
"deprecated": false,
"produces": [
"application/json"
],
"parameters": [
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"error": {
"type": "boolean",
"default": false
},
"message": {
"type": "string"
},
"data": {
"type": "object"
}
}
}
},
"500": {
"description": "",
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"default": false
},
"error": {
"type": "boolean"
},
"message": {
"type": "string"
},
"data": {
"type": "object"
}
}
}
}
}
}
}
},
"tags": [
{
"name": "entity-master-controller",
"description": "Entity Master Controller"
}
],
"corsConfiguration": {
"accessControlAllowOrigins": ["https://dtdevsso.ril.com"],
"accessControlAllowHeaders":[
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods":[
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": "true",
"corsConfigurationEnabled": "true"
}
}
In this swagger file, inspite of adding the CORS payload, it is not reflected after publishing the API through the swagger file.
To setup CORS support you must first define an OPTIONS method in your resource that returns the required headers.
All paths in swagger need a cors option chunk. this is the chunk.
"/users":
{
"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"
}
}
}
}
}
}
For more details you can visit this link
I used the following payload for creating/updating an API in WSO2.
It is working perfectly. Sorry for the delayed update on this.
{
"name": "%apiName%",
"description": "%apiDescription%",
"context": "/%apiName%",
"version": "%apiVersion%",
"provider": "%apiProvider%",
"apiDefinition": "%swaggger_extended.json% // Input swagger file",
"wsdlUri": null,
"status": "CREATED",
"responseCaching": "Disabled",
"cacheTimeout": 300,
"destinationStatsEnabled": false,
"isDefaultVersion": false,
"type": "HTTP",
"transport": [
"http",
"https"
],
"tags": ["%apiTags%"],
"tiers": ["%apiTiersCollection%"],
"visibility": "%apiVisibility%",
"visibleRoles": [],
"endpointConfig": "%endPointConfig%",
"gatewayEnvironments": "Production and Sandbox",
"subscriptionAvailability": null,
"subscriptionAvailableTenants": [],
"businessInformation": {
"businessOwnerEmail": "%BizOwnerName#ril.com%",
"technicalOwnerEmail": "%TechOwnerName#ril.com%",
"technicalOwner": "%TechOwnerName%",
"businessOwner": "%BizOwnerName%"
},
"corsConfiguration": {
"accessControlAllowOrigins": ["originURL"],
"accessControlAllowHeaders": [
"authorization",
"Access-Control-Allow-Origin",
"Content-Type",
"SOAPAction"
],
"accessControlAllowMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"PATCH",
"OPTIONS"
],
"accessControlAllowCredentials": false,
"corsConfigurationEnabled": true
}
}

AWS APIGateway CloudFormation specify Api Key required for method?

I have the below CloudFormation template which creates my API Gateway (backed by Lambda). I want to enable API Keys as a requirement for one or more of these methods. I have successfully created API Keys, Usage Plans and the association between the two, but can't figure out how to actually enable the 'requires API Key' property for some of the methods. The documentation from AWS specifies an 'ApiKeyRequired' property as a part of the AWS::ApiGateway::Method component, but my CF template doesn't have or use this component? I'm unsure how to use it considering I've never required it before?
My template is below:
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Description":"This is a placeholder for the description of this web api",
"ApiKeySourceType":"HEADER",
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/list/tables": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableList.Arn}/invocations"
}
},
"security": [
{
"api_key": []
}
],
"responses": {}
}
},
"/list/columns/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetColumnList.Arn}/invocations"
}
},
"responses": {}
}
},
"datagw/general/table/get/{tableid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableResponse.Arn}/invocations"
}
},
"responses": {}
}
},
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${Get.Arn}/invocations"
}
},
"responses": {}
}
},
"/tables/{tableid}/{columnid}": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetTableBasic.Arn}/invocations"
}
},
"responses": {}
}
},
"securityDefinitions": {
"type": "api_key",
"name": "x-api-key",
"in": "header"
}
},
"swagger": "2.0"
}
}
},
I think adding security under each path and then securityDefinitions under paths would work.
"paths": {
"/list/tables": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-
03-31/functions/${GetTableList.Arn}/invocations"
}
},
"security": [
{
"api_key": []
}
]
}
}
},
"securityDefinitions": {
"type": "api_key",
"name": "x-api-key",
"in": "header"
}
I ran into the same issue and resolved it by abandoning the use of the Body property in the AWS::ApiGateway::RestApi using:
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"DependsOn": "AspNetCoreFunction",
"Properties": {
"Description":"My Api Gateway",
"ApiKeySourceType" : "HEADER",
"EndpointConfiguration" : { "Types" : [ "REGIONAL" ]}
}
},
Then, I created a proxy resource. In your case, you would create a resource for each of your paths. Where I have, "{proxy+}", you would have "/list/tables."
"ProxyResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"ParentId": {
"Fn::GetAtt": [
"ServerlessRestApi",
"RootResourceId"
]
},
"PathPart": "{proxy+}"
}
},
Finally, I was able to define an AWS::ApiGateway::Method then enforce usage an API key:
"CoreApiPostMethod":
{
"Type": "AWS::ApiGateway::Method",
"DependsOn" : ["AspNetCoreFunction", "ServerlessRestApi"],
"Properties":
{
"AuthorizationType" :"NONE",
"OperationName" : "My API Post Request",
"ApiKeyRequired" : true,
"ResourceId": { "Ref": "ProxyResource" },
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"HttpMethod" : "POST",
"Integration" : {
"ConnectionType" : "INTERNET",
"IntegrationHttpMethod" : "POST",
"Type" : "AWS_PROXY",
"Uri" : {
"Fn::Sub":"arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AspNetCoreFunction.Arn}/invocations"
}
}
}
},
And then follow the same pattern for the other HTTP methods. It's more verbose than the original configuration, but it does give you more control over the method configuration.
Late to the party.
"x-amazon-apigateway-api-key-source" : "HEADER",
And
"securityDefinitions": {
"<SOME_NAME>": {
"type": "apiKey",
"name": "x-api-key",
"in": "header"
}
}
And
"security" : [{
"<SOME_NAME>" : []
}]
So a possible working solution could be
"Body": {
"swagger": "2.0",
"info": {
"version": "2017-01-27T21:44:58Z",
"title": {"Ref": "AWS::StackName"}
},
"basePath": "/bbd",
"x-amazon-apigateway-api-key-source" : "HEADER",
"schemes": [
"https"
],
"paths": {
"/{proxy+}": {
"x-amazon-apigateway-any-method": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "proxy",
"in": "path",
"required": true,
"type": "string"
}
],
"security" : [{
"bbd" : []
}],
"responses": {},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200"
}
},
"uri": "<URL>",
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"cacheNamespace": "xh7gp9",
"cacheKeyParameters": [
"method.request.path.proxy"
],
"contentHandling": "CONVERT_TO_TEXT",
"type": "aws_proxy"
}
}
}
},
"securityDefinitions": {
"bbd": {
"type": "apiKey",
"name": "x-api-key",
"in": "header"
}
}
}
Complete guide here. This guide provides a basic setup for enabling API keys for any API Gateway methods.
Use AWS::Serverless::Api for defining your API. It supports an Auth attribute which has an attribute named ApiKeyRequired. Set this to true.
Following code snippet from the above guide should do.
AuthApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
ApiKeyRequired: 'true' # This makes passing ApiKey mandatory
DefinitionBody:
swagger: '2.0'
info: ...
"security" : [{
"myKey" : []
}],
"myKey": {
"type": "apiKey",
"name": "x-api-key",
"in": "header"
},
Adding security element in body and myKey element in securityDefinitions worked for me.

AWS Cloud Formation template fails with Invalid mapping expression parameter specified

I am working on an AWS Cloud Formation template for an endpoint with a path like /user/{uid}/cart. I need to create an integration with an HTTP host. I've been attempting to map {uid} into the Integration Request URL Path Parameters like so:
"x-amazon-apigateway-integration": {
"uri": "http://${stageVariables.httpHost}/user/{uid}/cart",
"contentHandling": "CONVERT_TO_TEXT",
"timeoutInMillis": 29000,
"connectionType": "INTERNET",
"httpMethod": "PUT",
"passthroughBehavior": "WHEN_NO_MATCH",
"type": "HTTP_PROXY",
"requestParameters": {
"integration.request.path.uid" : "method.request.path.uid"
}...
I keep getting this error and I'm not sure what I'm doing wrong.
Errors found during import: Unable to put integration on 'PUT' for resource at path '/user/{uid}/cart': Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression parameter specified: method.request.path.uid]
Here's the full template
{
"Parameters": {
"AccessControlAllowOrigin": {
"Type": "String",
"Default": "*"
}
},
"Resources": {
"ConfigApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Body": {
"swagger": "2.0",
"tags": [
{
"name": "users",
"description": "secure user calls"
}
],
"schemes": [
"https"
],
"paths": {
"/user/{uid}/cart": {
"parameters": [
{
"name": "uid",
"in": "path",
"description": "user id",
"required": true,
"type": "string",
"format": "uuid"
}
],
"put": {
"tags": [
"users",
"cart"
],
"summary": "When called, this endpoint completes the user cart and puts their cart into their library",
"operationId": "completeusercart",
"description": "Completes the user cart\n",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "the user identifier",
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
},
"schema": {
"type": "string"
}
}
},
"x-amazon-apigateway-integration": {
"uri": "http://${stageVariables.httpHost}/user/{uid}/cart",
"contentHandling": "CONVERT_TO_TEXT",
"timeoutInMillis": 29000,
"connectionType": "INTERNET",
"httpMethod": "PUT",
"passthroughBehavior": "WHEN_NO_MATCH",
"type": "HTTP_PROXY",
"requestParameters": {
"integration.request.path.uid" : "method.request.path.uid"
},
"responses": {
"default": {
"responseModels": {
"application/json": "Empty"
},
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": {
"Fn::Sub": "'${AccessControlAllowOrigin}'"
},
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
},
"statusCode": "200"
}
}
}
},
"options": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
}
}
},
"x-amazon-apigateway-integration": {
"httpMethod": "OPTIONS",
"passthroughBehavior": "WHEN_NO_MATCH",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"type": "MOCK",
"timeoutInMillis": 29000,
"responses": {
"2\\d{2}": {
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": {
"Fn::Sub": "'${AccessControlAllowOrigin}'"
},
"method.response.header.Access-Control-Allow-Methods": "'PUT,OPTIONS'",
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
},
"statusCode": "200"
},
"4\\d{2}": {
"statusCode": "403"
},
"5\\d{2}": {
"statusCode": "403"
}
}
}
}
}
},
"definitions": {
"Empty": {
"type": "object",
"title": "Empty Schema"
}
}
}
}
},
"ConfigApiStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "ApiDeployment"
},
"MethodSettings": [
{
"DataTraceEnabled": true,
"HttpMethod": "*",
"LoggingLevel": "INFO",
"ResourcePath": "/*"
}
],
"RestApiId": {
"Ref": "ConfigApi"
},
"Variables": {
"httpHost": "0.0.0.0"
},
"StageName": "LATEST"
}
},
"ApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "ConfigApi"
},
"StageName": "DummyStage"
}
}
}
}
Thanks for your help!
The issue was the placement of the parameters. These need to be under the PUT rather than under the path.
"paths": {
"/user/{uid}/cart": {
"put": {
"tags": [
"users",
"cart"
],
"parameters": [
{
"name": "uid",
"in": "path",
"description": "user id",
"required": true,
"type": "string",
"format": "uuid"
}
],...