Skip to content
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

Updates schema docs to clarify unevaluatedProperties use #2247

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dakota002
Copy link
Contributor

Description

The listed example included 'unevaluatedProperties':false but did not include the '$schema': true property. Any schema that copied this format would fail validation.

This updates the docs to be more explicit about how they are tied together

@dakota002 dakota002 requested a review from lpsinger May 1, 2024 12:19
@lpsinger
Copy link
Member

lpsinger commented May 1, 2024

Are we sure that we are using $schema here correctly? I don't see anything in the documentation that suggests that this field can be a boolean.

@dakota002
Copy link
Contributor Author

It's kinda flexible, true just tells the validation to expect the field to be there, but we could also just set it to be { "type": "string" } which might be at least more consistent with the rest of the schema structures

@lpsinger
Copy link
Member

lpsinger commented May 1, 2024

It's kinda flexible, true just tells the validation to expect the field to be there

Is our validation correct, though? Where in the JSON Schema specification is this described?

@dakota002
Copy link
Contributor Author

Yea, our validation is correct, here is the docs page https://json-schema.org/understanding-json-schema/reference/object#unevaluatedproperties

It's not specified that you need to define it this way, it is just a consequence of including the $schema in a file, as it is naturally an optional property, and the unevaluatedproperties is basically just enforcing a strict mode

@lpsinger
Copy link
Member

lpsinger commented May 1, 2024

I simply don't see anything in the documentation that suggests that this is valid, or any examples of this usage. Maybe I'm being dense. Would you walk me through this?

@dakota002
Copy link
Contributor Author

I simply don't see anything in the documentation that suggests that this is valid, or any examples of this usage. Maybe I'm being dense. Would you walk me through this?

No worries!

TLDR: We could replace $schema in the example files with any other name for a property, it is just a field we are using to tell our validation script which schema file to compare to.

From our validation script:

      const schemaId = example['$schema']
      if (!schemaId) {
        process.exitCode = 1
        console.error(`error: ${path}: missing required $schema property`)
        return
      }

      try {
        ajv.validate(schemaId, example)
      } catch (e) {
       ...
      }

In the actual .schema files, this field is used "correctly" to declare a dialect: https://json-schema.org/understanding-json-schema/basics#declaring-a-json-schema

For the examples, we more or less just chose to use that to specify which gcn schema corresponds to an example. We could rename it to "schema" (no "$") or anything else and it would still work as expected, so long as we also update the validation script.

So I think technically the correct way of using it would be to include it in the properties and define it as a string type, possibly with some other info as defined here.

This somewhat ties into an idea I was working on for a Base schema that all alert schema would inherit from by default. The Base would apply these configurations in itself, so individual schemas wouldn't need to include them in their own definitions

@lpsinger
Copy link
Member

lpsinger commented May 6, 2024

Thanks for explaining this to me. I understand, now. As you explained, {"$schema": true} declares this as a custom property that must be present, regardless of its type. That's too broad; {"$schema": 123} or {"schema": "foobar"} would satisfy that.

The governing part of the specification is https://json-schema.org/draft/2020-12/json-schema-core#name-the-schema-keyword:

The "$schema" keyword is both used as a JSON Schema dialect identifier and as the identifier of a resource which is itself a JSON Schema, which describes the set of valid schemas written for this particular dialect.

The value of this keyword MUST be a URI [RFC3986] (containing a scheme) and this URI MUST be normalized. The current schema MUST be valid against the meta-schema identified by this URI.

In other words, the specification calls for JSON Schema to contain a $schema key-value pair. The source of my confusion was thinking that the specification also calls for $schema to be present in JSON resources whose structure conforms to a given schema, but the specification says no such thing. That is a convention of our own invention.

I agree: we should define the $schema field in a core schema. I suggest that we define it the same way as the JSON Schema meta-schema describes it (https://json-schema.org/draft/2020-12/meta/core), as {"$schema": {"type": "string", "format": "uri"}}.

Would that base schema be inherited by all of our core schema, or should we ask missions to inherit from it explicitly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants