Cleaning up the Sparks folder

This commit is contained in:
Richard Kranendonk 2026-05-18 09:31:41 +02:00
parent eb610a79b6
commit 96cd8fea7b
78 changed files with 149 additions and 181 deletions

View file

@ -0,0 +1,237 @@
---
tags:
- json
- supabase
---
# JSON Schema validation for Postgres
When using the JSON (or JSONB) datatype, the data needs to be validated to assure database integrity.
pg_jsonschema is a PostgreSQL extension for SupaBase that can validate `json` and `jsonb` data types against a JSON Schema. The extension offers two functions:
```java
-- Validates a json *instance* against a JSON Schema *schema*
json_matches_schema(schema json, instance json) returns bool
-- Validates a jsonb *instance* against a JSON Schema *schema*
jsonb_matches_schema(schema json, instance jsonb) returns bool
```
JSON Schema is a way to define what valid JSON should look like for a particular use case:
- What properties an object should have
- What data types are expected
- Which fields are required vs optional
- Validation constraints (like minimum/maximum values, string patterns, etc.)
- Default values and descriptions
A JSON Schema is itself a JSON document. Here's a simple example of a JSON schema:
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Person's full name"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["name", "email"]
}
```
You can check input against a schema in SQL like this:
```sql
create table some_table(
id serial primary key, -- db-column `id` column is an auto-incrementing primary key
metadata json not null, -- db-column `metadata` must contain a JSON value and cannot be null
check ( -- table-level check constraint to match the JSON in `metadata` to the schema
json_matches_schema(
schema :='{
"type": "object", -- we require an object ...
"properties": {
"foo": { -- with a single string property `"foo"` ...
"type": "string"
}
},
"required": ["foo"], -- property `"foo"` is required ...
"additionalProperties": false -- and no additional properties are allowed
}',
instance := metadata -- the value of the `metadata` column is passed ...
-- as the `instance` argument to the `json_matches_schema` function, for each row
)
)
);
-- Now we can attempt to insert a row into `some_table`,
-- with the `metadata` value provided as `<SQL input>`
insert into some_table(metadata)
values
(<SQL input>);
-- <SQL input> needs to be replaced with an actual JSON value, e.g. '{"foo": "bar"}'.
-- The insert will only succeed if the contents of `metadata` matches the schema in the check constraint.
```
## Validating for a set of allowed values
Use the `enum` keyword to validate that a value must be one of a specific set of allowed values.
**String values:**
```json
{
"type": "string",
"enum": ["red", "green", "blue"]
}
```
**Mixed data types:**
```json
{
"enum": ["active", "inactive", null, 42]
}
```
**In an object property:**
```json
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["pending", "approved", "rejected"]
},
"priority": {
"type": "integer",
"enum": [1, 2, 3, 4, 5]
}
}
}
```
## Validating for a data range
**Inclusive bounds (default):**
```json
{
"type": "integer",
"minimum": 1,
"maximum": 10
}
```
This allows values from 1 to 10, including 1 and 10.
**Exclusive bounds:**
```json
{
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 100
}
```
This allows values greater than 0 and less than 100, but not 0 or 100 themselves.
**Mixed Bounds:**
```json
{
"type": "number",
"minimum": 0,
"exclusiveMaximum": 1
}
```
This allows values from 0 (inclusive) to 1 (exclusive), so 0 ≤ value < 1.
**One-Sided Ranges:**
```json
{
"type": "integer",
"minimum": 18
}
```
```json
{
"type": "number",
"maximum": 3.14159
}
```
**In Object Properties:**
```json
{
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"temperature": {
"type": "number",
"minimum": -273.15,
"maximum": 1000.0
}
}
}
```
**Regex Validation:**
```json
{
"type": "string",
"pattern": "^[a-zA-Z0-9]+$"
}
```
**Date Validation:**
JSON Schema supports the ISO 8601 date format:
```json
{
"type": "string",
"format": "date"
}
```
`"date"` validates dates like: `2023-12-25`
`"date-time"` validates like: `2023-12-25T10:30:00Z` or `2023-12-25T10:30:00.123Z`
`"time"` validates like: `10:30:00` or `10:30:00.123`
Using the ISO 8601 date format is recommended for interoperability.
Custom date patterns can be validated with Regex.
Ranges can be validated using the `"minimum"` and `"maximum"` keywords like before.
## Documentation**
- [pg_jsonschema](https://github.com/supabase/pg_jsonschema)
- [JSON Schema](https://json-schema.org/)