-
-
Notifications
You must be signed in to change notification settings - Fork 309
"missing" or "defaultProperties" annotation keyword #867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
That is a good point about |
Alternative names could be e.g. "undefinedValues", "defaultValues" or simply "defaults" (plural). We may also want to consider an array form, for tuples, or function arguments. One more thing to consider is that "default" does not have to be valid according to the schema. "missing" would have to be, since by definition the behavior is the same. |
The thing that needs to be explicitly stated here is that (given the description above) the I think this is an incorrect behavior. Core section 9.3.2.1 doesn't state that the property subschema may be skipped if the property is absent, however it does have
which may be interpreted as "don't bother validating properties that aren't there." I think the proper way to implement this is to process a property's subschema, even if the property is absent. Doing this allows |
On whose part? This isn't a defined behavior, so much as a logical consequence of how we've defined
What would this even mean? It's not meaningful to run undefined against a JSON Schema, as undefined is not valid JSON. And there's no other precedent for such a feature. And even if we did, that wouldn't fix the problem this keyword is addressing. "default" is allowed to be invalid as an instance, or show a different behavior than omitting the property. e.g. #858 Maybe bring your point up as a new issue? |
I think @awwright is correct about the implications of how we've defined applicators and annotations to work. Of course, that's all fairly new and we can tweak it if we want to. It's also important to think about generative use cases vs validation use cases. Generative use cases work without an instance, and are really where the
In truth, While I get the point of the If that does not solve the problem, I would be open to a keyword such as this in the future. I am also happy that describing the behaviors of annotations and applicators have given us a sane way to talk about In the meantime, if someone wanted to do this as an extension keyword, that would also be a good way to explore its utility. @awwright would you be OK with moving this to the vocabularies repository for now? If we try the generative stuff with the OpenAPI folks and that doesn't work, but a trial run extension keyword finds adoption, we can "promote" the issue back to this repo. Does that seem reasonable to you as well @gregsdennis? |
@handrews I think this should be kept next to "default"—if anything, this keyword would be used more often than "default" would. Also, another naming idea: |
Yeah, I noticed the issue around how I would suggest actually what we have, and failed to recoginise, is a different class of annotation. It's a "LOCATION ANNOTATION KEYWORD", not just an annotation keyword. It's an annotation relating to the location, not the instance data. My knee jerk reaction is to suggest removing it till we can properly define it, however I am ill informed as to the implications for OpenAPI, if any. (Of course, they could define their own logic for how to use Further, it sounds like a class of keywords we need to define and allow for, especially given, as you've pointed out, there's a class of activities (generation and auto complete in IDEs) which we haven't considered because "those are for vocabularies, man". That's fine, but recognising there's a separate class of keyword which can and likely will be used outside of the "apply schema to instance to get annotations" framework for collecting annotations. I'm not even 75% "LOCATION ANNOTATION KEYWORD" is the correct phrasing, because it's no longer an annotation when used in the context outside of applying the schema. "structural information keyword" maybe or something similar? Open to further discussion. I think we need to hold moving this to vocabularies repo till we decide if we should define (in a very limited way) a new class of keywords. |
This needs more context. So this comes from the idea that the JSON instances is ultimately going to be deserializing into a model, and for me, that means .Net. When deserializing in .Net, if a property is missing, knowing what the default should be is important because the property has to be populated with some value. When not specified, the default value for the property's type is used. But if the schema specifies a non-.Net-type-default, that value should be used. If |
@gregsdennis I think a good question to ask is whether that deserialization is part of validation, or part of a form of code generation. Meaning, would it make sense to scan for defaults up front and then look them up as you realize you have a missing value? @Relequestual I'll come back to your comment when I have a bit more time. For now, I agree that there's something interesting going on here that warrants continued discussion in this repo. |
It's the other way around. You'd want to validate that the JSON matches your models prior to deserialization. So validation can become part of deserialization, though not strictly required. This is where having those annotations (e.g. from |
As part of this deserialization, once you have a value supplied by |
@gregsdennis I agree (I think) with what you say about validation before deserialization. But I guess I'm really thinking of three phases, which might not make any sense for C#/.NET, which I've never known well and haven't looked at at all for over a decade. I'm thinking in terms of:
Clearly, this is not the way you're thinking about it and since you understand the language you're working in and I don't, I'm assuming I have something wrong here. But I'd like to understand better what that is. |
I think that In the application I know best, the schema is loaded with "default" values for properties which are intended to do three things: (1) Document the application semantics behind the interface-- telling the user "you may choose a value for this parameter but if you don't it will take on the specified 'default' value"; (2) Guide people or processes to generate documents-- telling them how to specify functionally-required parameters completely (as by showing them in a UI and/or adding them to each document) but distinguishing which of those parameters have default values (also useful as initial values displayed in UI when creating a new doc) versus those which must be filled by the user (or which are truly optional, depending on and, the part that causes the most trouble, (3) Tell the document parser/validator to supply (insert) missing properties with specified values-- in order to achieve the semantics (1) when the document generator (2) leaves something out, which is very common, as when a human whomps up a minimum-acceptable-doc ( AJV's useDefaults option gets (3) done well for the application I mentioned (thank you @epoberezkin ), but now I understand better how special that is, since missing properties do not, as @awwright pointed out, actually match anything in the schema for normal validation purposes. Note that I have not yet thought through multiple-applicable Perhaps like this: if present, If (If we could start from scratch we might revise the names, like |
In my opinion, the entire "default" concept should be removed to promote correct solution architecture. Schema validation is a read-only pass/fail concept, of course it should never be relied on to alter the data (as it seems you all generally agree), but even "missing value" suggestions should not be defined here either. The concept of default values is contextual... when you're storing values, your storage system may consider certain "defaults", when you're exposing data to API users, that may consider entirely different "defaults", no one should be led to believe that the core data schema should carry that information in a properly designed system. |
Yes, this is a good way to think about it.
This is a fair point, but that doesn't mean there cannot be a concept of a default value in JSON Schema. It just means that annotation and validations are different functions and sometimes they don't overlap. |
Another idea for a keyword name: "fill" or "fillProperties" (as in, "fill in these missing values") |
I would go with |
I wonder if we really need new keywords. Seems like all current use of For example: {
"default": {
"foo": "bar",
"bar": "baz"
},
"properties": {
"foo": true,
"bar": true
}
} Same applies to arrays. You can have That would likely be a simpler (we can argue people have just been using it wrong) and less confusing change than introducing a whole set of new keywords and leaving the former |
I'm strongly against reinterpreting Personally, I think it's fine how it is. The alternative is too unintuitive and I think it's ok that it doesn't make sense as an annotation. |
I'm also against redefining the keyword on the grounds that it has well-establish semantics. I think we need to introduce a new keyword (proposal) and deprecate
The problem lies in the annotative scenario where the instance is missing a property. This is the same problem that draft 3 Similarly, This has no impact on validation, it fixes annotation, and it's a breaking change (but a manageable one) for generation. On
|
I get the problem on changing the semantics of I don't have a solution. Just thinking out loud that if we want to resolve this somehow, we will create confusion either ways :/ |
The "default" keyword is one of the most misused & abused annotation keywords due to consequences of how JSON Schema works.
It is frequently assumed that if a property in an instance document is missing, the "default" keyword lets you create that property and fill in that value as if it has the same behavior.
But this is not actually the case. The biggest reason is the "default" keyword does not produce an annotation unless the property exists in the instance in the first place... defeating the point.
The "default" keyword is mostly useful for user interface and IDE work, where a user indicates they want to create a value, and so the "default" keyword can provide a sensible initial default in these cases. For example:
A user creates a new record in a document database (like a MongoDB collection). The interface creates an instance of the schema, reading the "default" keyword to provide a value; instead of creating a blank document (which is invalid JSON).
A user in an IDE is typing
{ "name":
and then tab-completes in the default value, an empty string (as opposed to e.g. a number, or another object).However, all the time, users seem to think you can substitute in the "default" value for a missing one:
This also seemed sensible to me until I realized that "default" doesn't produce an annotation if the instance is absent.
I'm proposing a keyword that does mean exactly this: it means "if the instance is an object, and it is missing any of the given properties, the behavior will be the same as if it were defined with the specified value".
Example schema:
This would allow implementations to infer that this:
will behave the same as this:
Some implementations or tools might even offer a way to return a copy of the instance with these values filled in. This would be useful for applications that want to both validate user input, and fill in defaults; instead of having to perform these as separate operations.
The text was updated successfully, but these errors were encountered: