Vivek
Vivek

Reputation: 1

Error while creating models for request validation in aws api gateway

I am trying to build model for the request validation in the aws api gateway that i created.

In the model schema, when i use simple json schema, it works. But when i use my schema as below.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "uuid": {
      "type": "string",
      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
      "minLength": 36,
      "maxLength": 36
    },
    "macAddress": {
      "type": "string",
      "pattern": "([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})"
    },
    "locale": {
      "type": "string",
      "pattern": "^[a-z]{2}(-[A-Z]{2})?$",
      "minLength": 2
    },    
    "status": {
      "type": "string",
      "enum": ["good", "bad", "canceled"]
    },
    "timezone": {
      "type": "string",
      "pattern": "^[A-Z][a-z]+/[A-Z][a-z]+$"
    },
    "device": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "mac_address": {
          "type": "string",
          "$ref": "#/definitions/macAddress"
        },
        "hardware": {
          "type": "string"
        }
      },
      "required": ["mac_address"]
    },    
    "started_at": {
      "type": "number",
      "minimum": 0,
      "maximum": 2147483647999
    },
    "finished_at": {
      "type": "number",
      "minimum": 0,
      "maximum": 2147483647999
    },
    "questionType": {
      "enum": [
        "barcode",
        "name",
        "text"
      ]
    },
    "question": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "key": {
          "string"
        },
        "type": {
          "$ref": "#/definitions/questionType"
        }
      },
      "required": ["key", "type"]
    },
    "answers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "question": {
            "$ref": "#/definitions/question"
          },
          "status": {
            "type": "string",
            "$ref": "#/definitions/status"
          },
          "started_at": {
            "type": "number",
            "$ref": "#/definitions/started_at"
          },
          "finished_at": {
            "type": "number",
            "$ref": "#/definitions/finished_at"
          }
        },
        "allOf": [
            {"if": {
            "properties": { "question": { "properties": {
              "type": { "const": "text" }
            } } } },
           "then": {
            "properties": { "value": {"type": "string"} } }
          },
           {"if": {
            "properties": { "question": { "properties": {
              "type": { "const": "name" }
            } } } },
           "then": {
            "properties": { "value": {"type": "string" } } }
          },
          {"if": {
            "properties": { "question": { "properties": {
              "type": { "const": "barcode" }
            }} } },
           "then": {
            "properties": { "value": {"type": "string" } } }
          }
        ] 
      }
    }
  },
  "properties": {
    "locale": {
      "$ref": "#/definitions/locale"
    },
    "timezone": {
      "$ref": "#/definitions/timezone"
    },
    "device": {
      "$ref": "#/definitions/device"
    },
    "answers": {
      "$ref": "#/definitions/answers"
    }
  },
  "required": ["locale"]
}
 

I get the below error.

validation error detected: Value 'Invalid model specified: Validation Result: warnings : [], errors : [Invalid model schema specified. Unsupported keyword(s): ["if","then"], Invalid model schema specified.

When i read the aws documentation, i see that the json schema draft 4 is supported and i have also used the draft 4 rules to build my schema.

Is there a hack to use the if/then in aws model schema or how can i build the schema without if then?

Upvotes: 0

Views: 1127

Answers (2)

Dakota Hipp
Dakota Hipp

Reputation: 809

I too found you cannot use draft-07 for API gateway model validators. You may be able to get around the lack of if, then, and const to create variable validation paths by using "enum": ["SomeKey"] and oneOf or anyOf

  "oneOf": [{
    "$ref": "#/definitions/SomeDefinition"
  },
  {
    "$ref": "#/definitions/SomeOtherDefinition"
  }]

I was able to find a combination that worked for me using this online validator. https://www.jsonschemavalidator.net/

Here is a more complete example of what I used.

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "definitions": {
    "SomeAction": {
      "type": "object",
      "required": [
        "action",
        "body"
      ],
      "properties": {
        "action": {
          "enum": ["SomeAction"]
        },
        "body": {
          "type": "object",
          "required": [
            "userId"
          ],
          "properties": {
            "userId": {
              "type": "string"
            }
          }
        }
      }
    },
    "SomeOtherAction": {
      "type": "object",
      "required": [
        "action",
        "body"
      ],
      "properties": {
        "action": {
          "enum":["SomeOtherAction"]
        },
        "body": {
          "type": "object",
          "required": [
            "leagueId"
          ],
          "properties": {
            "leagueId": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "type": "object",
  "required": ["action"],
  "properties": {
    "action": {
        "enum": [
            "SomeAction",
            "SomeOtherAction"
        ]
    }
  },
  "oneOf": [{
    "$ref": "#/definitions/SomeAction"
  },
  {
    "$ref": "#/definitions/SomeOtherAction"
  }]
}

Upvotes: 0

dmunicio
dmunicio

Reputation: 1

In the first line of the schema you are using draft-07:

"$schema": "http://json-schema.org/draft-07/schema#"

AWS API Gateway currently only supports draft-04 and if/then feature is only supported from draft-07:

https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else

As far as I know, currently the only way is to move the validation to the lambda behind the API Gateway endpoint.

Upvotes: 0

Related Questions