acornejo/jjv

"required" check is run before defaults are applied

Closed this issue · 2 comments

Hi there – firstly, thanks for the awesome project.

I think there is an issue in the parse order, but this may just be me misunderstanding the schema proposal.

My understanding is that the following should be valid because the req_field default should be applied and satisfy it's "required" requirement:

var schema = {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": ["req_field"],
  "properties": {
    "req_field": {
      "type": "string",
      "default": "DEFAULT"
    },
    "opt_field": {
      "type": "string"
    }
  }
}
var value = {
  "opt_field": "cool beans",
};

var err = env.validate(schema, value, {checkRequired: true, useDefault: true, useCoerce: false, removeAdditional: false})

console.log(err);
// prints: { validation: { req_field: { required: true } } }

This quick and dirty workaround produces the expected result:

var err1 = env.validate(schema, value, {checkRequired: false, useDefault: true, useCoerce: false, removeAdditional: false})
var err2 = env.validate(schema, value, {checkRequired: true, useDefault: false, useCoerce: false, removeAdditional: false})

console.log(err1, err2);
// prints: null null

Is this a bug, or am I just thinking of this wrong?

Hi Mike, I'm glad you have found JJV useful.

My interpretation of the required/default fields on the JSON schema draft v4 specification is different than yours.

Namely, I believe that if a field is required, then it should be provided by the user, otherwise what is the purpose of making it required???

To say it differently. Consider a schema where the field req_field is not required but contains a default value. If the user submits a valid value in req_field, it will be accepted, if it submits nothing, then the default value will be used and it will be accepted too.

If this is the behavior you wanted out of the schema, then what do you gain by adding the required qualifier to the property? i.e. what scenario are you trying to cach by combining required with default that you couldn't do without it?

If you believe my interpretation to be wrong, please submit a bug report to the mantainers of the JSON-schema specification adding a new test that exhibits the behavior. As of today JJV passes the official test suite, if that test suite changes I will gladly modify JJV to pass the new specification.

Closing for the moment.

Hi Alex! Thanks so much for the thorough reply. After your explanation, I definitely see where you're coming from, and I see that you're right. The spec itself seems quite vague on the use of required and default, and even though I've read through it looking for clarification on this issue, I can't find much. I think that I'm applying the idea of required to the parser's output, while you're (correctly) applying it to its input.

My idea of "required" comes from the SQL-esque "datatype NOT NULL" behavior, where the database either receives an explicit value or provides its default; For the sake of others who might come in with this mindset, allow me to clarify:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": ["req_field","req_def_field"],
  "properties": {
    "req_field": {
      "type": "string",
    },
    "req_def_field": {
      "type": "string",
      "default": "REQ"
    },
    "opt_field": {
      "type": "string"
    },
    "opt_def_field": {
      "type": "string",
      "default": "OPT"
    }
  }
}

In the above example, an instance is required to contain explicit values for both req_field and req_def_field and the default value of req_def_field will always be ignored. While both opt_field and opt_def_field are technically optional, opt_def_field will always be set after being parsed by JJV (assuming the useDefault config is set to true).

This makes perfect sense to me. Thanks again for the clarification and the great library.

Cheers,
Mike