Using the AWS API Gateway SDK for Javascript - javascript
I'm trying to use the AmzaonWebService Api Gateway SDK for Javascript without success.
I've all the time the console error message : "Access Control Allow origin missing"
This is how I do:
dataFactory.setConfig = function() {
var config = {
accessKey: 'xxxxxxxxxxxxxx', // AWS Access KEY ID
secretKey: 'xxxxxxxxxx/xxxxxxxxxx/xxxxxxxx', // AWS Secret Key ID
sessionToken: dataFactory.getCognitoCredentials().idToken.jwtToken,
region: 'eu-west-1',
apiKey: undefined,
defaultContentType: 'application/json',
defaultAcceptType: 'application/json'
};
return config
}
var apigClient = apigClientFactory.newClient(dataFactory.setConfig());
dataFactory.getAll = function() {
var params = {
headers: {
"Access-Control-Allow-Origin": "*"
}
}
apigClient.allGet(params).then(function(res) {
console.log(res);
return res
}).catch(function(res) {
console.log(res);
})
};
This is how I'm getting the credentials:
dataFactory.getCognitoCredentials = function() {
var res;
var poolData = {
UserPoolId: 'eu-west-1_xxxxxxxx',
ClientId: 'xxxxxxxxxxxxxxx'
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
var cognitoUser = userPool.getCurrentUser();
if (cognitoUser != null) {
cognitoUser.getSession(function(err, session) {
if (err) {
alert(err);
return;
}
res = session
});
}
return res;
}
Does someone know what I'm doing wrong ?
You need to setup the CORS headers on API Gateway's response and an OPTION method as a pre-flight method. I have an example swagger file which has CORS setup. You might want to take a look.
{
"swagger": "2.0",
"info": {
"description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
"title": "PetStore"
},
"schemes": [
"https"
],
"paths": {
"/": {
"get": {
"tags": [
"pets"
],
"description": "PetStore HTML web page containing API usage information",
"consumes": [
"application/json"
],
"produces": [
"text/html"
],
"responses": {
"200": {
"description": "Successful operation",
"headers": {
"Content-Type": {
"type": "string",
"description": "Media type of request"
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Content-Type": "'text/html'"
},
"responseTemplates": {
"text/html": "<html>\n <head>\n <style>\n body {\n color: #333;\n font-family: Sans-serif;\n max-width: 800px;\n margin: auto;\n }\n </style>\n </head>\n <body>\n <h1>Welcome to your Pet Store API</h1>\n <p>\n You have succesfully deployed your first API. You are seeing this HTML page because the <code>GET</code> method to the root resource of your API returns this content as a Mock integration.\n </p>\n <p>\n The Pet Store API contains the <code>/pets</code> and <code>/pets/{petId}</code> resources. By making a <code>GET</code> request to <code>/pets</code> you can retrieve a list of Pets in your API. If you are looking for a specific pet, for example the pet with ID 1, you can make a <code>GET</code> request to <code>/pets/1</code>.\n </p>\n <p>\n You can use a REST client such as Postman to test the <code>POST</code> methods in your API to create a new pet. Use the sample body below to send the <code>POST</code> request:\n </p>\n <pre>\n{\n \"type\" : \"cat\",\n \"price\" : 123.11\n}\n </pre>\n </body>\n</html>"
}
}
},
"passthroughBehavior": "when_no_match",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"type": "mock"
}
}
},
"/pets": {
"get": {
"tags": [
"pets"
],
"summary": "List all pets",
"produces": [
"application/json"
],
"parameters": [
{
"name": "type",
"in": "query",
"description": "The type of pet to retrieve",
"required": false,
"type": "string"
},
{
"name": "page",
"in": "query",
"description": "Page number of results to return.",
"required": false,
"type": "string"
}
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/Pets"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string",
"description": "URI that may access the resource"
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"requestParameters": {
"integration.request.querystring.page": "method.request.querystring.page",
"integration.request.querystring.type": "method.request.querystring.type"
},
"uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "http"
}
},
"post": {
"tags": [
"pets"
],
"operationId": "CreatePet",
"summary": "Create a pet",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "NewPet",
"required": true,
"schema": {
"$ref": "#/definitions/NewPet"
}
}
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/NewPetResponse"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string",
"description": "URI that may access the resource"
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
"passthroughBehavior": "when_no_match",
"httpMethod": "POST",
"type": "http"
}
},
"options": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/Empty"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string",
"description": "URI that may access the resource"
},
"Access-Control-Allow-Methods": {
"type": "string",
"description": "Method or methods allowed when accessing the resource"
},
"Access-Control-Allow-Headers": {
"type": "string",
"description": "Used in response to a preflight request to indicate which HTTP headers can be used when making the request."
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Methods": "'POST,GET,OPTIONS'",
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"passthroughBehavior": "when_no_match",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"type": "mock"
}
}
},
"/pets/{petId}": {
"get": {
"tags": [
"pets"
],
"summary": "Info for a specific pet",
"operationId": "GetPet",
"produces": [
"application/json"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "The id of the pet to retrieve",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/Pet"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string",
"description": "URI that may access the resource"
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"requestParameters": {
"integration.request.path.petId": "method.request.path.petId"
},
"uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{petId}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "http"
}
},
"options": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "The id of the pet to retrieve",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/Empty"
},
"headers": {
"Access-Control-Allow-Origin": {
"type": "string",
"description": "URI that may access the resource"
},
"Access-Control-Allow-Methods": {
"type": "string",
"description": "Method or methods allowed when accessing the resource"
},
"Access-Control-Allow-Headers": {
"type": "string",
"description": "Used in response to a preflight request to indicate which HTTP headers can be used when making the request."
}
}
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'",
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
}
}
},
"passthroughBehavior": "when_no_match",
"requestTemplates": {
"application/json": "{\"statusCode\": 200}"
},
"type": "mock"
}
}
}
},
"definitions": {
"Pets": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
},
"Empty": {
"type": "object"
},
"NewPetResponse": {
"type": "object",
"properties": {
"pet": {
"$ref": "#/definitions/Pet"
},
"message": {
"type": "string"
}
}
},
"Pet": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"price": {
"type": "number"
}
}
},
"NewPet": {
"type": "object",
"properties": {
"type": {
"$ref": "#/definitions/PetType"
},
"price": {
"type": "number"
}
}
},
"PetType": {
"type": "string",
"enum": [
"dog",
"cat",
"fish",
"bird",
"gecko"
]
}
},
"x-amazon-apigateway-documentation": {
"version": "v2.1",
"createdDate": "2016-11-17T07:03:59Z",
"documentationParts": [
{
"location": {
"type": "API"
},
"properties": {
"info": {
"description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints"
}
}
},
{
"location": {
"type": "METHOD",
"method": "GET"
},
"properties": {
"tags": [
"pets"
],
"description": "PetStore HTML web page containing API usage information"
}
},
{
"location": {
"type": "METHOD",
"path": "/pets/{petId}",
"method": "GET"
},
"properties": {
"tags": [
"pets"
],
"summary": "Info for a specific pet"
}
},
{
"location": {
"type": "METHOD",
"path": "/pets",
"method": "GET"
},
"properties": {
"tags": [
"pets"
],
"summary": "List all pets"
}
},
{
"location": {
"type": "METHOD",
"path": "/pets",
"method": "POST"
},
"properties": {
"tags": [
"pets"
],
"summary": "Create a pet"
}
},
{
"location": {
"type": "PATH_PARAMETER",
"path": "/pets/{petId}",
"method": "*",
"name": "petId"
},
"properties": {
"description": "The id of the pet to retrieve"
}
},
{
"location": {
"type": "QUERY_PARAMETER",
"path": "/pets",
"method": "GET",
"name": "page"
},
"properties": {
"description": "Page number of results to return."
}
},
{
"location": {
"type": "QUERY_PARAMETER",
"path": "/pets",
"method": "GET",
"name": "type"
},
"properties": {
"description": "The type of pet to retrieve"
}
},
{
"location": {
"type": "REQUEST_BODY",
"path": "/pets",
"method": "POST"
},
"properties": {
"description": "Pet object that needs to be added to the store"
}
},
{
"location": {
"type": "RESPONSE",
"method": "*",
"statusCode": "200"
},
"properties": {
"description": "Successful operation"
}
},
{
"location": {
"type": "RESPONSE_HEADER",
"method": "OPTIONS",
"statusCode": "200",
"name": "Access-Control-Allow-Headers"
},
"properties": {
"description": "Used in response to a preflight request to indicate which HTTP headers can be used when making the request."
}
},
{
"location": {
"type": "RESPONSE_HEADER",
"method": "OPTIONS",
"statusCode": "200",
"name": "Access-Control-Allow-Methods"
},
"properties": {
"description": "Method or methods allowed when accessing the resource"
}
},
{
"location": {
"type": "RESPONSE_HEADER",
"method": "*",
"statusCode": "200",
"name": "Access-Control-Allow-Origin"
},
"properties": {
"description": "URI that may access the resource"
}
},
{
"location": {
"type": "RESPONSE_HEADER",
"method": "GET",
"statusCode": "200",
"name": "Content-Type"
},
"properties": {
"description": "Media type of request"
}
}
]
}
}
Related
What value do I insert inside the 'Body' parameter of my API request according to this API Specification?
I'm trying to make a data request from a URL based on the data provider's API specification. My app is built using the Node.JS and NPM. I'm subscribed to use the API and I've verified that all my identity credentials, policies and IAM keys that give me permission to access the API. Could someone please help me define the correct value to place inside the 'Body' parameter of my API request based on the API specification provided by the URL. Thanks! My current request parameter code looks like below: const request_parameter = { DataSetId: "xxxxxac09b4xxxxxxxxxx", RevisionId: "xxxxxxc8df94fxxxxxxx", AssetId: "xxxxxxx2bde1fa3xxxxxxx", Method: "POST", Path: "/pxxx/graphql", QueryStringParameters: { param1: " ", param2: " " }, RequestHeaders: { "Content-Type": "application/json" }, Body: {\"body_param\":\"body_param_value\"} // FIX ME }; The data provider's actual API specification looks like below: { "openapi": "3.0.1", "info": { "title": "image-services", "description": "API Gateway for integration of Platform Services into AWS Data Exchange", "version": "2022-03-03T20:04:18Z" }, "servers": [ { "url": "" } ], "paths": { "/psdm/graphql": { "post": { "requestBody": { "description": "GraphQL query for the Catalog in the form of:\n\n `{\n availablemetadatarecord(\n QUERYPARAMS\n ) { \n FIELDLIST\n } \n }`\n", "content": { "application/graphql": { "schema": { "$ref": "#/components/schemas/CatalogSearchRequest" }, "examples": { "Limit returned data": { "description": "Limit the number of records in a response.\n\nIn your query, simply specify `limit: <int>` \n", "value": "{\n availablemetadatarecord(\n limit: 10\n content: { catalogProperties: { vendor: { eq: \"EYE\" } } }\n ) {\n assignedId\n }\n}\n" } } } }, "required": true }, "responses": { "200": { "description": "200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CatalogSearchResponse" } } } } }, "security": [ { "sigv4": [] } ] } } }, "components": { "schemas": { "CatalogSearchRequest": { "title": "CatalogSearchRequest", "type": "object" }, "CatalogSearchResponse": { "title": "Catalog Search Response", "required": [ "data", "paginationInfo" ], "type": "object", "properties": { "paginationInfo": { "type": "object", "properties": { "recordsInPage": { "type": "integer" }, "nextOffset": { "type": "integer" } } }, "data": { "type": "object", "properties": { "availablemetadatarecord": { "type": "array", "description": "Records returned by query", "items": { "type": "object" } } } } } } }, "securitySchemes": { "sigv4": { "type": "apiKey", "name": "Authorization", "in": "header", "x-amazon-apigateway-authtype": "awsSigv4" } } } }
Having trouble writing the correct GraphQL query in Node.JS for an AWS DataExchange Provider's API specification
I'm trying to write a GraphQL query to fetch data from an AWS DataExchange provider based on their company's API specification. However, every query I've written so far isn't returning any data. I've verified that all my AWS credentials and IAM keys are correct. Could you please help me write the correct query based on the API specification given by the data provider. My current request 'body' looks like below: Body: JSON.stringify({ content: { "application/graphql": { "schema": { "$ref": "#/components/schemas/CatalogSearchRequest" }, query: `query availablemetadatarecord(limit: 10 content: { catalogProperties: { vendor: { eq: "EYE" } } }) { assignedId } }` } } }), The DataExchange provider's actual API specification looks like below. { "openapi": "3.0.1", "info": { "title": "image-services", "description": "API Gateway for integration of Platform Services into AWS Data Exchange", "version": "2022-03-03T20:04:18Z" }, "servers": [ { "url": "" } ], "paths": { "/psdm/graphql": { "post": { "requestBody": { "description": "GraphQL query for the Catalog in the form of:\n\n `{\n availablemetadatarecord(\n QUERYPARAMS\n ) { \n FIELDLIST\n } \n }`\n", "content": { "application/graphql": { "schema": { "$ref": "#/components/schemas/CatalogSearchRequest" }, "examples": { "Limit returned data": { "description": "Limit the number of records in a response.\n\nIn your query, simply specify `limit: <int>` \n", "value": "{\n availablemetadatarecord(\n limit: 10\n content: { catalogProperties: { vendor: { eq: \"EYE\" } } }\n ) {\n assignedId\n }\n}\n" } } } }, "required": true }, "responses": { "200": { "description": "200 response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CatalogSearchResponse" } } } } }, "security": [ { "sigv4": [] } ] } } }, "components": { "schemas": { "CatalogSearchRequest": { "title": "CatalogSearchRequest", "type": "object" }, "CatalogSearchResponse": { "title": "Catalog Search Response", "required": [ "data", "paginationInfo" ], "type": "object", "properties": { "paginationInfo": { "type": "object", "properties": { "recordsInPage": { "type": "integer" }, "nextOffset": { "type": "integer" } } }, "data": { "type": "object", "properties": { "availablemetadatarecord": { "type": "array", "description": "Records returned by query", "items": { "type": "object" } } } } } } }, "securitySchemes": { "sigv4": { "type": "apiKey", "name": "Authorization", "in": "header", "x-amazon-apigateway-authtype": "awsSigv4" } } } }
Remote method in LoopBack not being called
When calling a remote method in my LoopBack project, it seems to only return an empty array. I don't think it is really being called at all but perhaps the default implementation is being called. member.js module.exports = function(Member) { Member.getProjectsForMember = function(id, callback) { console.error('HERE'); return callback(null, {'test': '123'}); }; }; member.json { "name": "member", "base": "User", "idInjection": true, "options": { "validateUpsert": true }, "properties": { "name": { "type": "string", "required": true } }, "validations": [], "relations": { "projects": { "type": "hasMany", "model": "project", "options": { "nestRemoting": false } } }, "acls": [{ "accessType": "*", "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW" }, { "accessType": "*", "principalType": "ROLE", "principalId": "$unauthenticated", "permission": "DENY" } ], "methods": { "getProjectsForMember": { "accepts": [{ "arg": "id", "type": "number", "required": true, "http": { "source": "path" } }], "returns": [{ "arg": "projects", "type": "Object", "root": true, }], "http": [{ "path": "/:id/projects", "verb": "get" }] } } } I am calling it using the LoopBack API Explorer via a GET to /members/{id}/projects: http://localhost:3000/api/members/3e26u0aa62155715vcb52afa/projects?access_token=R6GKVHwFuMG2caJexuyoMd0JSNOWtvLVXIEmRj1IkNSrM54bwomQLxHcpqlyFaHk The response is []. I would expect to see the response of {'test': '123'} and the 'HERE' logged to the terminal but I do not.
Post request with array
I want to test my Web API with a postman on the javascript app. I have the following swagger. "/attachment/erase": { "post": { "summary": "Erase ", "consumes": [ "application/json" ], "produces": [ "application/json" ], "parameters": [ { "name": "folder", "in": "query", "type": "string", "description": "folder('s) detail", "required": true }, { "name": "type", "in": "query", "type": "string", "description": "ABC or BCD", "required": true }, { "name": "body", "in": "body", "required": true, "schema": { "type": "object", "required": ["files"], "properties": { "attachments": { "type": "array", "items": { "type": "string" } } } }, "description": "The file(s) to delete" } ], "responses": { "200": { "description": "file(s) erased." } } } } So I send the following request : with the following body : In return, I get an error 415. What I am doing wrong?
You're sending x-www-form-urlencoded when the API is expecting application/json.
How about passing a form-data parameter file, please refer the image
Validate an API response against JSON schema using AJV
I have many days reading a lot and doing several tests with this, without the expected results. I need validate an API response with its JSON schema (Swagger 2.0). The JSON is longer but I've reduced it to simply. I need to know if "code" and "message" keywords in the response have the type and values defined. Here the code I'm using: var Ajv = require('ajv'); var ajv = new Ajv(); var schema = { "host": "cert", "paths": { "products": { "get": { "responses": { "401": { "description": "Problem with the client request", "headers": { "x-correlator": { "type": "string", "format": "uuid", "description": "Correlation id" } }, "schema": { "$ref": "file:///../errors.json#/definitions/Unauthenticated" } } } } }, "products": { "get": { "responses": { "401": { "description": "Problem with the client request", "headers": { "x-correlator": { "type": "string", "format": "uuid", "description": "Correlation id" } }, "schema": { "$ref": "file:///../errors.json#/definitions/Unauthenticated" }, "examples": { "application/json": { "code": "UNAUTHENTICATED", "message": "Authentication error" } } } } } } } } var errors_schema = { "info": { "description": "Common errors", "version": "3.0.1", "title": "Common errors", "contact": { "name": "Team" } }, "definitions": { "ModelError": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string", "description": "A human readable description" } } }, "Unauthenticated": { "allOf": [ { "type": "object", "required": [ "code" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHENTICATED" ], "default": "UNAUTHENTICATED", "description": "Request not authenticated due to missing, invalid, or expired credentials." } } }, { "$ref": "#/definitions/ModelError" } ] } } } ajv.addSchema(errors_schema, 'file:///../errors.json'); var testajv = ajv.compile(schema); var response = {"code": 123, "message":"token expired"} var valid = testajv(response); console.log(valid); if(!valid) { console.log(testajv.errors); } As you see the keyword "code" in the response is '123' integer but in the schema it is defined as string. Independently of the value the validation always gets 'true'. What should I do to get my needs? Thanks in advance.
Swagger schema contains multiple JSON schemas organized in API structure, you need to address a correct part of Swagger schema to employ JSON schema for validation. Please check example code (https://runkit.com/embed/bwj42juwyjo4): var Ajv = require('ajv'); var ajv = new Ajv(); var schema = { "host": "cert", "paths": { "products": { "get": { "responses": { "401": { "description": "Problem with the client request", "headers": { "x-correlator": { "type": "string", "format": "uuid", "description": "Correlation id" } }, "schema": { "$ref": "errors.json#/definitions/Unauthenticated" } } } } }, "products": { "get": { "responses": { "401": { "description": "Problem with the client request", "headers": { "x-correlator": { "type": "string", "format": "uuid", "description": "Correlation id" } }, "schema": { "$ref": "errors.json#/definitions/Unauthenticated" }, "examples": { "application/json": { "code": "UNAUTHENTICATED", "message": "Authentication error" } } } } } } } } var errors_schema = { "info": { "description": "Common errors", "version": "3.0.1", "title": "Common errors", "contact": { "name": "Team" } }, "definitions": { "ModelError": { "type": "object", "required": [ "message" ], "properties": { "message": { "type": "string", "description": "A human readable description" } } }, "Unauthenticated": { "allOf": [ { "type": "object", "required": [ "code" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHENTICATED" ], "default": "UNAUTHENTICATED", "description": "Request not authenticated due to missing, invalid, or expired credentials." } } }, { "$ref": "#/definitions/ModelError" } ] } } } ajv.addSchema(errors_schema, 'errors.json'); ajv.addSchema(schema, 'swagger.json') var testajv = ajv.compile({ $ref: 'errors.json#/definitions/Unauthenticated' }); console.log(testajv({"code": 123, "message":"token expired"}), testajv.errors); // Fails console.log(testajv({"code": "AAA", "message":"token expired"}), testajv.errors); // Fails console.log(testajv({"code": "UNAUTHENTICATED", "message":"token expired"}), testajv.errors); // Passes var testajv2 = ajv.compile({ $ref: 'swagger.json#/paths/products/get/responses/401/schema' }); console.log(testajv2({"code": 123, "message":"token expired"}), testajv2.errors); // Fails console.log(testajv2({"code": "AAA", "message":"token expired"}), testajv2.errors); // Fails console.log(testajv2({"code": "UNAUTHENTICATED", "message":"token expired"}), testajv2.errors); // Passes Some more information in relevant ajv issue: https://github.com/epoberezkin/ajv/issues/195
Use type as number instead of string in code property. "properties": { "code": { "type": "number", "enum": [ "UNAUTHENTICATED" ], "default": "UNAUTHENTICATED", "description": "Request not authenticated due to missing, invalid, or expired credentials." } }