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

Fix: Bad contrast in the blog's dark theme in info boxes #1143

Merged
merged 13 commits into from
Dec 21, 2024
11 changes: 11 additions & 0 deletions components/StyledMarkdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ const StyledMarkdownBlock = ({ markdown }: { markdown: string }) => {
</p>
),
},
specialBox: {
component: ({ children }) => {
return (
<div className='bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700 dark:bg-blue-900 dark:border-blue-400 dark:text-blue-200'>
{children}
</div>
);
},
},

a: {
component: ({ children, href, title, className }) => {
if (!href) return children;
Expand Down Expand Up @@ -665,6 +675,7 @@ export function TableOfContentMarkdown({
'figure',
'Bigquote',
'Regularquote',
'specialBox',
),
},
}}
Expand Down
67 changes: 35 additions & 32 deletions pages/blog/posts/applicability-json-schema-fundamentals-part-1.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "It all starts with applicability - JSON Schema Fundamentals part 1"
date: "2022-03-21"
title: 'It all starts with applicability - JSON Schema Fundamentals part 1'
date: '2022-03-21'
tags:
- Fundamentals
type: Engineering
Expand All @@ -10,14 +10,13 @@ authors:
photo: /img/avatars/benhutton.webp
link: https://www.x.com/relequestual
byline: JSON Schema Specification Lead @Postman
excerpt: "We explore the fundamental JSON Schema concepts: Applicability, Subschemas, and Assertion Boolean Logic - Everyone needs good fundamentals."
excerpt: 'We explore the fundamental JSON Schema concepts: Applicability, Subschemas, and Assertion Boolean Logic - Everyone needs good fundamentals.'
---

"Validation begins by applying the root Schema to the complete instance document. Applicator keywords apply subschemas to the instance location." - Borrowed from [JSON Schema in 5 minutes](https://json-schema.org/blog/posts/json-schema-in-5-minutes).

The primary use case for JSON Schema is validation. Therefore it's imperative to understand precisely how the validation process happens. Let's take a little time to properly grasp the fundamental JSON Schema concept of Applicability.


# Applicator keywords

JSON Schema consists of many keywords. These keywords can be broken down into categories, one of which is "applicator". In the physical sense, an "applicator" is a thing you use to introduce one substance to another. For example, a cloth might be used to introduce polish to a nice wooden table. The cloth is the applicator. The polish is applied to the table via the cloth.
Expand All @@ -30,23 +29,21 @@ The validation process for JSON Schema begins with applying the whole JSON Schem

A JSON Schema may be a Boolean or an Object. In the introductory article mentioned above, we noted how a Boolean Schema of `true` or `false` resulted in the same assertion result (true and false respectivly) regardless of the instance data. We also noted how the equivalent Object Schemas were `{ }` and `{ "not": { } }` respectively. (The `not` keyword inverts the assertion result.)

<div className="bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700">
<specialBox>
<p className="font-bold"><svg className="w-6 h-6 mr-2 float-left mt-0" xmlns="https://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clipRule="evenodd" /></svg>Vocabulary check</p>
<p>An "assertion" is a statement of fact. This is used in reference to the result of testing in Computing. The test might be called "X is 1". If the test passes, the assertion is true!</p>
</div>
</specialBox>

When we talk about the whole Schema in terms of application, we usually refer to it as the "root Schema". This is because the other Schemas which are applied to specific instance locations are different, and we call them "subschemas". Differentiating between the root Schema and subschemas allows us to communicate with clarity which JSON Schema we're talking about, and when to use the Schema as part of the validation process.

<div className="bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700">
<specialBox>
<p>The following examples assume to be using JSON Schema 2020-12. Where there are things you should know about previous versions (or drafts) of JSON Schema, it will be highlighted.</p>
</div>

</specialBox>

# Subschema application - Validating Objects and Arrays

If your JSON instance is an Object or an Array, you'll likely want to validate the values of the Object or the items in the Array. In this introduction, you'll be using the `properties` and `items` keywords, and subschemas.


## Validating Objects

Let's jump into an example. Here's our instance data.
Expand Down Expand Up @@ -85,6 +82,8 @@ OK, let's check our Schema does all we need it to. What happens when our instanc
"isEmailConfirmed": "true"
}
// isEmailConfirmed should be a Boolean, not a string.


// Will cause validation error.
```

Expand All @@ -98,7 +97,7 @@ We need to make sure we define the appropriate constraint if we want any keys to
"email": { "type": "string" },
"isEmailConfirmed": { "type": "boolean" }
},
"required": [ "id", "name", "email" ]
"required": ["id", "name", "email"]
}
```

Expand All @@ -112,6 +111,8 @@ We can now be confident that if our required fields are missing, validation will
"isEmaleConfirmed": "true"
}
// Typo for key "isEmaleConfirmed".


// Validates because of applicability.
```

Expand All @@ -127,16 +128,16 @@ Luckily, picking this up with our Schema is simple. The `additionalProperties` k
"email": { "type": "string" },
"isEmailConfirmed": { "type": "boolean" }
},
"required": [ "id", "name", "email" ],
"required": ["id", "name", "email"],
"additionalProperties": false
}
```

The value of `additionalProperties` is not just a Boolean, but a Schema. This subschema value is applied to all values of the instance object that are not defined in the `properties` object in our example. You could use `additionalProperties` to allow additional properties, but constrain their values to be a String.

<div className="bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700">
<specialBox>
<p>There is a little simplification here to help us understand the concept we're looking to learn. If you want to dig a little deeper, check out our <a href="https://json-schema.org/understanding-json-schema/reference/object.html#additional-properties" target="_blank">learning resources on `additionalProperties`</a>.</p>
</div>
</specialBox>

Finally, what if we expect an Object, but are given an Array or another non-object type?

Expand All @@ -149,6 +150,8 @@ Finally, what if we expect an Object, but are given an Array or another non-obje
"isEmaleConfirmed": "true"
}
]


// An array is not an object...
```

Expand All @@ -165,7 +168,7 @@ The three keywords we've explored so far, `properties`, `required`, and `additio
"email": { "type": "string" },
"isEmailConfirmed": { "type": "boolean" }
},
"required": [ "id", "name", "email" ],
"required": ["id", "name", "email"],
"additionalProperties": false
}
```
Expand All @@ -174,12 +177,11 @@ In summary, for the soundest validation, we must express all the constraints we

Note, `type` takes an Array of types. It may be that your instance is allowed to be an Object or an Array, and constraints for both can be defined within the same Schema Object.


## Validating Arrays

<div className="bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700">
<specialBox>
<p>In this introduction, we're only going to be covering how things work for JSON Schema 2020-12. If you're using a previous version, including "draft-7" or prior, you will likely benefit from digging a little deeper into the <a href="https://json-schema.org/understanding-json-schema/reference/array.html" target="_blank">learning resources for Array validation.</a></p>
</div>
</specialBox>

Let's step back to our previous example data, where we were provided with an Array as opposed to an Object. Let's say our data is now only allowed to be an Array.

Expand All @@ -195,7 +197,7 @@ To validate every item in the array, we need to use the `items` keyword. The `it
"email": { "type": "string" },
"isEmailConfirmed": { "type": "boolean" }
},
"required": [ "id", "name", "email" ],
"required": ["id", "name", "email"],
"additionalProperties": false
}
}
Expand All @@ -205,7 +207,6 @@ As with the applicability rules of `properties`, the value Schema of `items` is

There are other keywords that are applicable to arrays, but If I continue to explain all of them in detail, this article might start to turn into a reference book! Moving on...


# Apply but modify - Boolean logic with subschemas

JSON Schema applicator keywords can do more than just apply a subschema and take the resulting Boolean assertion. Applicator keywords can conditionally apply subschemas, and combine or modify any resulting assertions using boolean logic.
Expand All @@ -222,18 +223,19 @@ This sounds simple, but let's look at some examples.

```json caption="allOf/example1.schema.json"
{
"allOf": [ true, true, true]
"allOf": [true, true, true]
}
```

```json caption="allOf/example2.schema.json"
{
"allOf": [ true, false, true]
"allOf": [true, false, true]
}
```
<div className="bg-blue-200 border-l-4 border-blue-500 px-4 py-1 relative text-blue-700">

<specialBox>
<p><span className="font-bold">Remember:</span> A Boolean is a valid schema that always produces the assertion result of its value, regardless of the instance data.</p>
</div>
</specialBox>

Our first "allOf" example shows the array having three subschemas, which are all `true`. The results are combined using the boolean logic AND operator. The resulting assertion from the `allOf` keyword is `true`.

Expand All @@ -243,16 +245,15 @@ The `true` and `false` Boolean Schemas in this example could be any subschemas t

Let's take the two examples again, but use `anyOf` rather than `allOf`.


```json caption="anyOf/example1.schema.json"
{
"anyOf": [ true, true, true]
"anyOf": [true, true, true]
}
```

```json caption="anyOf/example2.schema.json"
{
"anyOf": [ true, false, true]
"anyOf": [true, false, true]
}
```

Expand Down Expand Up @@ -329,7 +330,8 @@ Let's go back to our array of people data, modify it, and say it represents an a
"email": "[email protected]",
"isStudent": true,
"year": 1
}, {
},
{
"name": "Alice",
"email": "[email protected]",
"isTeacher": true,
Expand All @@ -343,15 +345,16 @@ To start, let's do the same as we did when creating our first schema. Copy the i
```json caption="oneOf/example1.schema.json"
{
"items": {
"oneOf":[
"oneOf": [
{
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"isStudent": { "type": "boolean" },
"year": { "type": "number" }
}
}, {
},
{
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
Expand All @@ -376,7 +379,7 @@ Yikes! That's not what we want!

But why isn't it working? Why isn't the instance passing validation?

__What do we know?__
**What do we know?**

The validator is "failing fast". This means it's stopping after the first error.

Expand Down Expand Up @@ -430,4 +433,4 @@ All feedback is welcome. If you have questions or comments, you can find me on t
- [JSON Schema live playground (hyperjump validator) for all drafts (from draft-04)](https://json-schema.hyperjump.io)
- [Links to RFC specification documents](/specification)

Photo by Heidi Fin on [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
Photo by Heidi Fin on [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
Loading