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

cookbook page, with solutions to frequently asked questions #190

Open
Tracked by #158
karenetheridge opened this issue Apr 11, 2021 · 19 comments
Open
Tracked by #158

cookbook page, with solutions to frequently asked questions #190

karenetheridge opened this issue Apr 11, 2021 · 19 comments
Assignees
Labels
✨ Enhancement Indicates that the issue suggests an improvement or new feature. Priority: Low This issue can probably be picked up by anyone. Status: In Progress This issue is being worked on, and has someone assigned.

Comments

@karenetheridge
Copy link
Member

karenetheridge commented Apr 11, 2021

I am opening this as an issue rather than a PR to start, in order to gather feedback and additional content.

There are a number of questions that are asked frequently on stackoverflow, slack, github issues etc that come down to "how do I express this pattern in JSON Schema?" Here are a few of them, and I'm sure we can come up with more:

  • "evaluate this subschema but do not collect annotations" (not so common but it has come up a few times, and it is weird enough that it deserves a mention IMO):
    { not: { not: { ... subschema ... } } }

  • add descriptions to a bunch of enum values, e.g. for form generation:

  {
    anyOf: [
      {
        "description": "...",
        "const": "value0",
      },
      {
        "description": "...",
        "const": "value1",
      },
      ...
    ]
  }
  • simulate OpenAPI's "discriminator":
  {
    allOf: [
      {
        if: {
          type: object,
          required: [ "foo" ],
          properties: { foo: { const: "value0" } }
        },
        then: {
          .. subschema when data has foo: value0
        }
      },
      {
        if: {
          type: object,
          required: [ "foo" ],
          properties: { foo: { const: "value1" } }
        },
        then: {
          .. subschema when data has foo: value1
        }
      },
      {
        if: {
          type: object,
          required: [ "bar" ],
          properties: { bar: { const: "value0" } }
        },
        then: {
          .. subschema when data has bar: value0
        }
      },
      ...
    ],
}
@jdesrosiers
Copy link
Member

I love this. I've been talking with @Relequestual about improving JSON Schema's documentation and content like this is part of the long term plan. Ideally, I'd like to start with minimal updates to Understanding JSON Schema to bring it up to the latest draft. Then get a new website designed and built and port UJS content over. Then do more in-depth documentation plus cookbook, tutorials, and even blogs. Of course that's all very ambitious, so it's great that you're getting the cookbook content rolling.

I'm bookmarking this issue to add to when things occur to me.

@jdesrosiers
Copy link
Member

The "simulate OpenAPI's discriminator" example should include required in all the ifs. We can also include an example that uses this pattern with a default alternative (as described at https://json-schema.org/understanding-json-schema/reference/conditionals.html)

@jdesrosiers
Copy link
Member

Cookbook idea: contains for draft-04

Equivalent of "contains": { ... schema ... }

"not": {
  "items": {
    "not": { ... schema ... }
  }
}

Full example

{
  "type": "array",
  "allOf": [{ "$ref": "/#definitions/contains-foo" }],

  "definitions": {
    "contains-foo": {
      "not": {
        "items": {
          "not": { "$ref": "#/definitions/foo" }
        }
      }
    },
    "foo": { "const": "foo" }
  }
}

@jdesrosiers
Copy link
Member

jdesrosiers commented Apr 12, 2021

Cookbook idea: contains for object values

Pattern

"not": {
  "additionalItems": {
    "not": { ... schema ... }
  }
}

Full example

{
  "type": "object",
  "allOf": [{ "$ref": "/#definitions/contains-foo" }],

  "definitions": {
    "contains-foo": {
      "not": {
        "additionalProperties": {
          "not": { "$ref": "#/definitions/foo" }
        }
      }
    },
    "foo": { "const": "foo" }
  }
}

@jdesrosiers
Copy link
Member

jdesrosiers commented Apr 12, 2021

Cookbook idea: The "Implication Pattern" (if/then for draft-04/6)

Pattern: Equivalent to "if": { ... if schema ... }, "then": { ... then schema ... }

"anyOf": [
  { "not": { ... if schema ... } },
  { ... then schema ... }
]

Full Example

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "number" }
  },
  "allOf": [{ "$ref": "foo-bar-implies-bar-is-required" }],

  "definitions": {
    "foo-bar-implies-bar-is-required": {
      "anyOf": [
        {
          "not": {
            "properties": {
              "foo": { "const": "bar" }
            },
            "required": ["foo"]
          }
        },
        { "required": ["bar"] }
      ]
    }
  }
}

@karenetheridge
Copy link
Member Author

require propertyA OR propertyB, but not both:

{
  "type": "object",
  "properties": {
    "propertyA": { ... },
    "propertyB": { ... }
  },
  "oneOf": [
    {
      "required": ["propertyA"],
      "not": { "required": ["propertyB"] }
    },
    {
      "required": ["propertyB"],
      "not": { "required": ["propertyA"] }
    }
  ]
}

@jdesrosiers
Copy link
Member

The nots are unnecessary in the previous example because it uses oneOf.

@jdesrosiers
Copy link
Member

Cookbook idea: Multiple fields required as a unit.

"foo" and "bar" must both be present or neither

{
  "dependentRequired": {
    "foo": ["bar"],
    "bar": ["foo"]
  }
}

"foo", "bar", "baz", and "quux" must all be present or none at all

{
  "dependentRequired": {
    "foo": ["bar"],
    "bar": ["baz"],
    "baz": ["quux"],
    "quux": ["foo"]
  }
}

@karenetheridge
Copy link
Member Author

Cookbook idea: Multiple fields required as a unit.

Cute! a little confusing though! I've done this in the past:

{
  "type": "object",
  "oneOf": [
    { "required": ["foo","bar","baz","quux"] },
    {
      "properties": {
        "foo": false,
        "bar": false,
        "baz": false,
        "quux": false
      }
    }
  ]
}

@Relequestual
Copy link
Member

How do I validate deep nested data when I don't know where it is in the structure?

https://stackoverflow.com/a/67315446/89211

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "definitions": {
    "grandParentToChild": {
        "properties": {
          "grandParent": {
            "properties": {
              "parent": {
                "properties": {
                  "child": {
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
    }
  },
  "allOf": [
    {
      "$ref": "#/definitions/grandParentToChild"
    }
  ],
  "additionalProperties": {
    "$ref": "#"
  },
  "items": {
    "$ref": "#"
  }
}

@benjagm
Copy link
Collaborator

benjagm commented Nov 23, 2023

Added to the docs strategy issue: #158

@benjagm benjagm added the 📝 Documentation Indicates improvements or additions to documentation. label Nov 23, 2023
@benjagm benjagm added this to the Docs Release 3 milestone Nov 24, 2023
@benjagm
Copy link
Collaborator

benjagm commented Nov 28, 2023

How to manage schema versioning?

#197

@benjagm benjagm added Priority: Low This issue can probably be picked up by anyone. Status: Available No one has claimed responsibility for resolving this issue. labels Feb 20, 2024
@Akshaybagai52
Copy link
Contributor

Hi @benjagm
can you assign this issue to me
Thanks

@benjagm
Copy link
Collaborator

benjagm commented Mar 2, 2024

@Akshaybagai52 This is not an easy issue. We should start with PR including just some FAQ. I'd love this to be totally data driven. This means a json file in the data folder with the questions and answers so the page is just rendering whatever is in the json. Both fields allowing markdown. Thoughts?

@benjagm benjagm assigned Akshaybagai52 and unassigned jdesrosiers Mar 2, 2024
@benjagm benjagm added Status: In Progress This issue is being worked on, and has someone assigned. and removed Status: Available No one has claimed responsibility for resolving this issue. labels Mar 2, 2024
@Akshaybagai52
Copy link
Contributor

@Akshaybagai52 This is not an easy issue. We should start with PR including just some FAQ. I'd love this to be totally data driven. This means a json file in the data folder with the questions and answers so the page is just rendering whatever is in the json. Both fields allowing markdown. Thoughts?

Thanks for assigning this issue. Just gone through all the chat and will create a PR which contains FAQ in json format with all the markdown as discussed above.

@Akshaybagai52
Copy link
Contributor

@benjagm can you check this PR #429
you can get the page at /frequently-asked-questions

@benjagm benjagm added ✨ Enhancement Indicates that the issue suggests an improvement or new feature. and removed 📝 Documentation Indicates improvements or additions to documentation. labels Mar 6, 2024
@lalitkumawat1m
Copy link
Contributor

Hey @benjagm,
Is this issue still open?

@Akshaybagai52
Copy link
Contributor

continue in this PR #534

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Enhancement Indicates that the issue suggests an improvement or new feature. Priority: Low This issue can probably be picked up by anyone. Status: In Progress This issue is being worked on, and has someone assigned.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants