I am trying to create an api model from a swagger file (my-api.json) using Loopback's Swagger connector (assuming that's what this connector is for!).
However, when running the loopback-cli, I get the following error:
? Enter the swagger spec url or file path: my-api.json
Loading my-api.json...
events.js:183
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property '$ref' of null
at C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\generator-loopback\swagger\spec-loader.js:124:13
at baseClone (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:2641:27)
at C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:2711:34
at arrayEach (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:516:11)
at baseClone (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:2705:7)
at C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:2711:34
at arrayEach (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:516:11)
at baseClone (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:2705:7)
at Function.cloneDeepWith (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\lodash\lodash.js:11120:14)
at parseSpec (C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\generator-loopback\swagger\spec-loader.js:123:19)
at C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\generator-loopback\swagger\spec-loader.js:160:5
at C:\Users\Nick\AppData\Roaming\npm\node_modules\loopback-cli\node_modules\generator-loopback\swagger\spec-loader.js:86:11
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
Here's the my-api-json swagger file:
{
"swagger": "2.0",
"info": {
"description": "my description",
"version": "0.0.2",
"title": "my title",
"termsOfService": "TBD",
"contact": {
"name": "John Doe",
"url": "http://www.myname.com",
"email": "johndoe#aol.com"
},
"license": {
"name": "TBD",
"url": "http://www.myname.com"
},
"x-classificationRecord": "Classsification of this swagger file - APPROVED"
},
"basePath": "/myPath",
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"securityDefinitions": {
"AdminSecurity": {
"type": "apiKey",
"in": "query",
"name": "apikey"
}
},
"paths": {
"/admin/vcap": {
"get": {
"tags": [
"admin"
],
"security": [
{
"AdminSecurity": []
}
],
"x-swagger-router-controller": "misc_info_controller",
"operationId": "getVCAP",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTopicEntity": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTopicEntity",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTopic": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTopic",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllEntityFacets": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllEntityFacets",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTopicEntityFacets": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTopicEntityFacets",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTopicEntityRelation": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTopicEntityRelation",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTopicPropertyFacet": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTopicPropertyFacet",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAllTable13": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAllTable13",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblComponentType": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblComponentType",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblElement": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblElement",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblFeature": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblFeature",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblSymbolPlacementInst": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblSymbolPlacementInst",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblSymbolElementLink": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblSymbolElementLink",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/getAlltblSymol": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "getAlltblSymol",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/query/newQuery": {
"get": {
"tags": [
"database"
],
"x-swagger-router-controller": "db",
"operationId": "newQuery",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Success"
}
}
}
}
},
"definitions": {
"Generic": {
"properties": {
"message": {
"type": "string"
}
}
},
"GenericError": {
"required": [
"status",
"statusCode",
"error"
],
"properties": {
"status": {
"type": "string",
"description": "Status indicating there was an error, should always be error",
"enum": [
"error"
]
},
"statusCode": {
"type": "number",
"description": "HTTP Status Code for the error"
},
"error": {
"type": "string",
"description": "String indicating what the error was"
},
"trace": {
"type": "string",
"description": "Original Error Message providing more detail if available"
}
}
},
"ErrorResponse": {
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer"
},
"message": {
"type": "string"
}
}
}
}
}
Any tips on how to fix? Thank you.
Related
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.
I'm programming a swagger documentation with swagger 2.0 and the request containing an authorization header doesn't seem to work properly. In fact, when I add the token in the Authorize header then execute the query, it says loading indefinitely.
Loading request
I've been facing the same problem for 2 days and I don't find any topic dealing about my issue.
{
"swagger": "2.0",
"info": {
"description": "Swagger API",
"version": "1.0.0",
"title": "Swagger API",
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
},
"securityDefinitions": {
"Bearer": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
},
"paths": {
"/api/login": {
"post": {
"tags": ["Login"],
"summary": "Returns JWT",
"parameters": [
{
"in": "body",
"name": "Login body",
"description": "Login request used to obtain JWT",
"required": true,
"schema": {
"$ref": "#/components/Login"
}
}
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/api/devices": {
"get": {
"tags": ["Devices"],
"summary": "Returns all devices",
"security": {
"Bearer": []
},
"responses": {
"200": {
"description": "GET success"
},
"401": {
"description": "Missing header with jwt"
}
}
},
"post": {
"tags": ["Devices"],
"summary": "Deploy all devices",
"security": {
"Bearer": []
},
"parameters": [
{
"in": "body",
"name": "Devices POST body",
"description": "Deploy devices",
"required": true,
"schema": {
"$ref": "#/components/Devices"
}
}
],
"responses": {
"200": {
"description": "Device deployment succeed"
},
"401": {
"description": "Missing header with jwt"
}
}
}
}
},
"components": {
"Login": {
"type": "object",
"properties": {
"login": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
}
}
}
}
},
"Devices": {
"type": "object",
"properties": {
"devices": {
"type": "object",
"properties": {
"devEUILSBList": {
"type": "array",
"items": {
"type": "string"
}
},
"applicationID": {
"type": "integer"
},
"deviceProfileID": {
"type": "string"
}
}
}
}
}
}
}
Complementary information :
The backend is running with Flask
Swagger 2.0
I am getting this error after upgrading my api from .netcore2.2 to 3.1 and trying to generate using autorest with the --v3 switch
WARNING: Schema violation: Data does not match any schemas from
'oneOf'
I have tried with and without SerializeAsV2
I see from the Autorest docs that this warning is because of an supported feature.
anyOf, oneOf are not currently supported
In services.AddSwaggerGen I have
c.ParameterFilter<SwaggerEnumParameterFilter>();
c.SchemaFilter<SwaggerEnumFilter>();
where
public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
{
var type = context.ApiParameterDescription.Type;
if (type.IsEnum)
parameter.Extensions.Add("x-ms-enum", new OpenApiObject
{
["name"] = new OpenApiString(type.Name),
["modelAsString"] = new OpenApiBoolean(false)
});
}
public class SwaggerEnumFilter : ISchemaFilter
{
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (model == null)
throw new ArgumentNullException("model");
if (context == null)
throw new ArgumentNullException("context");
if (context.Type.IsEnum)
model.Extensions.Add(
"x-ms-enum",
new OpenApiObject
{
["name"] = new OpenApiString(context.Type.Name),
["modelAsString"] = new OpenApiBoolean(false)
}
);
}
}
[update]
After upgrading to Autorest 3.0.6244 the warnings have changed to errors and the error message ends with
post > parameters > 0)
If I don't use the v3 switch I get the error
FATAL: swagger-document/individual/schema-validator - FAILED
FATAL: Error: [OperationAbortedException] Error occurred. Exiting.
Process() cancelled due to exception : [OperationAbortedException] Error occurred. Exiting.
I can see in the swagger.json that the parameters property "name" is not generating correctly. Here it contains "body" whereas previously it contained "info"
"/api/FrameLookUp": {
"post": {
"tags": [
"Frame"
],
"operationId": "FrameLookup",
"consumes": [
"application/json-patch+json",
"application/json",
"text/json",
"application/*+json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "header",
"name": "Authorization",
"description": "access token",
"required": true,
"type": "String"
},
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/FrameRequest"
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/FrameResponse"
}
}
}
}
},
The controller is
[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api")]
public class FrameController : MyController
{
[ProducesResponseType(typeof(FrameResponse), StatusCodes.Status200OK)]
[HttpPost("FrameLookUp")]
public IActionResult FrameLookup([FromBody] FrameRequest info)
{
IMyResponse MyFunc(IMyRequest x) => FrameData.FrameLookUp(info);
return InnerMethod(MyFunc, info);
}
}
Update
I have also tried using the SwaggerParameter from Swashbuckle.AspNetCore.Annotations
[Update]
I am thinking that maybe I just need to try the release for issue 1766
I tried cloning the swashbuckle.aspnetcore repo but ran into this issue
[Update]
I added c.GeneratePolymorphicSchemas(); to the AddSwaggerGen options but it has not helped.
[Update]
Here is the first error message
ERROR: Schema violation: Data does not match any schemas from 'oneOf'
- https://localhost:44348/api-docs/v1/swagger.json:1951:8 ($.paths["/api/synchronise-management/get-product-images-Ids"].post.parameters)
Investigating line 1951 in swagger.json
In the working swagger ( generated from dotnet2.2 project ) the json looks very similar however the parameter order is swapped
The other difference I can see is the generated name of the parameter
I see from this question the error occurs in the same place
[Update]
when I add the --debug switch to the autorest call I get
/configuration
DEBUG: pipeline-emitter - END
DEBUG: configuration-emitter - END
DEBUG: swagger-document-override/md-override-loader - END
DEBUG: swagger-document/loader - END
DEBUG: swagger-document/individual/transform - START
DEBUG: swagger-document/individual/transform - END
DEBUG: swagger-document/individual/schema-validator - START
ERROR: Schema violation: Data does not match any schemas from 'oneOf'
- https://localhost:44348/api/v1/swagger.json:1951:8 ($.paths["/api/synchronise-management/get-product-images-Ids"].
[Update]
Here is the cut down json
{
"swagger": "2.0",
"info": {
"title": "myapi API31",
"description": "ASP.NET Core Web API",
"version": "v1"
},
"host": "localhost:44348",
"basePath": "/v1",
"schemes": [
"https"
],
"paths": {
"/api/Test": {
"get": {
"tags": [
"Auth"
],
"operationId": "Test",
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/api/RequestToken": {
"post": {
"tags": [
"Auth"
],
"operationId": "RequestToken",
"consumes": [
"application/json-patch+json",
"application/json",
"text/json",
"application/*+json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/TokenRequest"
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/TokenResponse"
}
}
}
}
},
"/api/FrameLookUp": {
"post": {
"tags": [
"Frame"
],
"operationId": "FrameLookup",
"consumes": [
"application/json-patch+json",
"application/json",
"text/json",
"application/*+json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "header",
"name": "Authorization",
"description": "access token",
"required": true,
"type": "String"
},
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/FrameRequest"
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/FrameResponse"
}
}
}
}
}
},
"definitions": {
"TokenRequest": {
"required": [
"password",
"username"
],
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"TokenResponse": {
"type": "object",
"properties": {
"tokenResult": {
"type": "string"
}
}
},
"FramePackTypeEnum": {
"enum": [
"NotApplicable",
"PipeRack",
"LwBVan",
"VanTray",
"Car",
"CarryBag"
],
"type": "string",
"x-ms-enum": {
"name": "FramePackTypeEnum",
"modelAsString": false
}
},
"FrameRequest": {
"type": "object",
"properties": {
"qCodeJobId": {
"format": "int32",
"type": "integer"
},
"quantity": {
"format": "int32",
"type": "integer"
},
"widthInMm": {
"format": "int32",
"type": "integer"
},
"heightInMm": {
"format": "int32",
"type": "integer"
},
"ePackingType": {
"$ref": "#/definitions/FramePackTypeEnum"
},
"userEmail": {
"type": "string"
}
}
},
"FrameCaseEnum": {
"enum": [
"Case0_NoBraces",
"Case1_1Vertical_0Horizontal",
"Case2_2Vertical_0Horizontal",
"Case3_NVertical_0Horizontal",
"Case4_0Vertical_1Horizontal",
"Case5_1Vertical_1Horizontal",
"Case6_2Vertical_1Horizontal",
"Case7_NVertical_1Horizontal",
"Case8_0Vertical_2Horizontal",
"Case9_1Vertical_2Horizontal",
"Case10_2Vertical_2Horizontal",
"Case11_NVertical_2Horizontal",
"Case12_0Vertical_NHorizontal",
"Case13_1Vertical_NHorizontal",
"Case14_2Vertical_NHorizontal",
"Case15_NVertical_NHorizontal"
],
"type": "string",
"x-ms-enum": {
"name": "FrameCaseEnum",
"modelAsString": false
}
},
"FrameResponse": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"caseNumber": {
"$ref": "#/definitions/FrameCaseEnum"
},
"memberPriceEachExGst": {
"format": "double",
"type": "number"
},
"retailPriceEachExGst": {
"format": "double",
"type": "number"
}
}
}
}
}
With the .netcore2.2 api the request generates as
"FrameRequest": {
"type": "object",
"properties": {
"qCodeJobId": {
"format": "int32",
"type": "integer"
},
"quantity": {
"format": "int32",
"type": "integer"
},
"widthInMm": {
"format": "int32",
"type": "integer"
},
"heightInMm": {
"format": "int32",
"type": "integer"
},
"ePackingType": {
"enum": [
"NotApplicable",
"PipeRack",
"LwBVan",
"VanTray",
"Car",
"CarryBag"
],
"type": "string",
"x-ms-enum": {
"name": "FramePackTypeEnum",
"modelAsString": false
}
},
"userEmail": {
"type": "string"
}
}
}
Here is the command line I am running
autorest --input-file=.\myswagger.json --output-folder=generated --csharp --namespace=DDD --debug
Some links which the author, Kirsten Greed, put in comments:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore#schema-filters
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/1766
https://stackoverflow.com/questions/63857310/could-not-find-a-part-of-the-path-d-dev-swashbuckle-aspnetcore-src-swashbuckle
From your swagger.json we can see the validation shows:
https://validator.swagger.io/validator/debug?url=https://raw.githubusercontent.com/heldersepu/hs-scripts/master/swagger/63783800_swagger.json
{
"schemaValidationMessages": [
{
"level": "error",
"domain": "validation",
"keyword": "oneOf",
"message": "instance failed to match exactly one schema (matched 0 out of 2)",
"schema": {
"loadingURI": "http://swagger.io/v2/schema.json#",
"pointer": "/definitions/parametersList/items"
},
"instance": {
"pointer": "/paths/~1api~1FrameLookUp/post/parameters/0"
}
}
]
}
that lead us to your code:
that type: "String" should be: type: "string" with all lower case the error goes away
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"
}
],...
We have option to get the value of DomainName in cloudformation template while creating a CloudFront Distribution using Fn::GetAtt function. But I could not find anywhere that how we get Origin's Id and DefaultCacheBehaviour's TargetOriginId dynamically?
Can I just use Ref to my S3 and ELB?
This is my code, I have used some parameters also and changed the Cloudfront code as well. Please check it once whether it is correct or not.
And it is throwing me an error called "Property validation failure: [Encountered unsupported properties in {/DistributionConfig/Origins/1/S3OriginConfig}: [HTTPSPort, HTTPPort, OriginProtocolPolicy]]"
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"ClientName": {
"Type": "String",
"Description": "Name of the Client"
},
"EnvName": {
"Type": "String",
"Description": "Name of the Environment"
}
},
"Resources": {
"distd2v0l803ay8odocloudfrontnet": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Enabled": true,
"DefaultRootObject": "index.html",
"PriceClass": "PriceClass_All",
"CacheBehaviors": [
{
"TargetOriginId": {
"Ref": "elbhtlbetaelb"
},
"PathPattern": "/app*",
"ViewerProtocolPolicy": "allow-all",
"MinTTL": 0,
"AllowedMethods": [
"HEAD",
"DELETE",
"POST",
"GET",
"OPTIONS",
"PUT",
"PATCH"
],
"CachedMethods": [
"HEAD",
"GET"
],
"ForwardedValues": {
"QueryString": true,
"Cookies": {
"Forward": "all"
}
}
},
{
"TargetOriginId": {
"Ref": "elbhtlbetaelb"
},
"PathPattern": "/api*",
"ViewerProtocolPolicy": "allow-all",
"MinTTL": 0,
"AllowedMethods": [
"HEAD",
"DELETE",
"POST",
"GET",
"OPTIONS",
"PUT",
"PATCH"
],
"CachedMethods": [
"HEAD",
"GET"
],
"ForwardedValues": {
"QueryString": true,
"Cookies": {
"Forward": "all"
}
}
}
],
"DefaultCacheBehavior": {
"TargetOriginId": {
"Ref": "s3htlbeta"
},
"ViewerProtocolPolicy": "allow-all",
"MinTTL": 0,
"AllowedMethods": [
"HEAD",
"DELETE",
"POST",
"GET",
"OPTIONS",
"PUT",
"PATCH"
],
"CachedMethods": [
"HEAD",
"GET"
],
"ForwardedValues": {
"Cookies": {
"Forward": "none"
}
}
},
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"s3htlbeta",
"DomainName"
]
},
"Id": {
"Ref": "s3htlbeta"
},
"S3OriginConfig": {
"OriginAccessIdentity": "origin-access-identity/cloudfront/EYD1QGO9CUDA2"
}
},
{
"DomainName": {
"Fn::GetAtt": [
"elbhtlbetaelb",
"DNSName"
]
},
"Id": {
"Ref": "elbhtlbetaelb"
},
"S3OriginConfig": {
"HTTPPort": "80",
"HTTPSPort": "443",
"OriginProtocolPolicy": "http-only"
}
}
],
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Locations": []
}
},
"ViewerCertificate": {
"CloudFrontDefaultCertificate": "true",
"MinimumProtocolVersion": "TLSv1"
}
}
}
},
"s3htlbeta": {
"Type": "AWS::S3::Bucket",
"Properties": {
"AccessControl": "Private",
"VersioningConfiguration": {
"Status": "Suspended"
}
}
}
},
"Description": "xxx-beta cloudformation template"
}
The DistributionConfig/Origins/ID field should just be a text name, it doesn't need to reference anything.
ie. Set DistributionConfig/Origins/ID to a string e.g. 'MyOriginBucket'
Then your CacheBehaviour TargetOriginId is also a string set to 'MyOriginBucket'
The only Ref required to your new bucket is in Origins/DomainName.
The purpose of the TargetOriginId is to point to the origin ID that you specified in the list of Origins, not point to the bucket name.