hyperjump-io / json-schema

JSON Schema Validation, Annotation, and Bundling. Supports Draft 04, 06, 07, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1
https://json-schema.hyperjump.io/
MIT License
224 stars 21 forks source link

Schema validation using discriminator mapping seems to fail #43

Closed oravecz closed 10 months ago

oravecz commented 11 months ago

Online tool shows that the JSON payload below is valid for the given JSON Schema.

My expectation is the discriminator criterion will indicate the payload for SINGLE_SELECT will contain a required value property.

When validated, the SINGLE_SELECT criterion is recognized as valid JSON, even though the value property is not present.

JSON

{
  "name": "search-1",
  "criteria": [
    {
      "categoryId": "roadClass",
      "criterion": "SINGLE_SELECT"
    }
  ]
}

Schema

$schema: "https://json-schema.org/draft/2020-12/schema"

type: object
properties:
  name: 
    type: string
  criteria:
    type: array
    items: 
      $ref: '#/components/schemas/SearchCriterion'

components:
  schemas:
    SearchCriterion:
      type: object

      properties:
        categoryId:
          type: string
          description: The category being queried
        criterion:
          $ref: '#/components/schemas/SearchCriterionEnum'

      required:
        - categoryId
        - criterion

      discriminator:
        propertyName: criterion
        mapping:
          SINGLE_SELECT: '#/components/schemas/SearchCriterionSingleSelect'

    SearchCriterionEnum:
      description: List of the different types of supported search criteria

      type: string

      enum:
        - PARTIAL_TEXT
        - NUMERIC_RANGE
        - SINGLE_SELECT
        - MULTI_SELECT
        - BOOLEAN

    SearchCriterionSingleSelect:
      description: |
        Returns true if the compared value matches the chosen value.
      allOf:
        - $ref: '#/components/schemas/SearchCriterion'
        - type: object
          properties:
            value:
              type: string
            temporal:
              $ref: '#/components/schemas/SearchCriterionTemporal'
          required:
            - value
jdesrosiers commented 11 months ago

You're misunderstanding how discriminator works. It doesn't effect the validation outcome. It just serves as meta-data that can optionally allow the validator to provide more helpful error output when using anyOf or oneOf. You don't have an anyOf or oneOf, so the discriminator has no effect at all.

Have a look at https://stackoverflow.com/questions/38717933/jsonschema-attribute-conditionally-required/38781027#38781027 to see some techniques for conditional validation. discriminator is intended to be used with the "Enum" pattern described in that post.

Also, keep in mind that discriminator isn't a JSON Schema keyword, it's an OpenAPI extension. That means that if you use $schema: 'https://json-schema.org/draft/2020-12/schema', it won't know what discriminator is and ignore it.

This implementation understands the OpenAPI 3.0 dialect (https://spec.openapis.org/oas/3.0/dialect) and the OpenAPI 3.1 dialect (https://spec.openapis.org/oas/3.1/dialect/base). If you use one of those with $schema, discriminator will be understood, but this implementation doesn't do anything special with the meta-data it provides.