Skip to main content

Data Modeling

Every table in Revisium is defined by a JSON Schema. You design the schema — the platform enforces it on every write, generates APIs from it, and transforms data automatically when the schema changes.

Define a Table

A table has a name, a schema (structure), and rows (data). Here's a products table:

{
"title": "iPhone 16 Pro",
"price": 999,
"inStock": true,
"description": "Latest flagship smartphone"
}

The schema defines what fields exist, their types, and default values. Any data that doesn't match the schema is rejected.

Schema Editor — products table with field type selector (string, number, boolean, object, array, foreign key, schemas, system fields)
Schema Editor — products table with field type selector (string, number, boolean, object, array, foreign key, schemas, system fields)

Field Types

String

Text values. The most common field type.

{ "title": "iPhone 16 Pro" }

Strings support optional formats for rendering and validation:

FormatDeclarationUsage
Plain text{ "type": "string" }Names, IDs, short text
Markdown{ "type": "string", "contentMediaType": "text/markdown" }Rich content, articles
HTML{ "type": "string", "contentMediaType": "text/html" }Raw HTML content
Date-time{ "type": "string", "format": "date-time" }ISO 8601 timestamps
Email{ "type": "string", "format": "email" }Email addresses

Number

Integer or decimal values.

{ "price": 999 }

Boolean

True/false values.

{ "inStock": true }

Object

Nested structure with its own fields. Objects can be nested to any depth.

{
"weight": 199,
"color": "Desert Titanium"
}

Array

Lists of values. Items can be any type — strings, numbers, objects, or even files.

Array of strings:

["5G", "USB-C", "ProMotion"]

Array of objects:

[
{ "color": "Desert Titanium", "storage": 256 },
{ "color": "Black Titanium", "storage": 512 }
]

Nested arrays — objects inside arrays can contain their own arrays:

[
{ "product": "iphone-16", "quantity": 2, "addons": ["case", "charger"] },
{ "product": "macbook-m4", "quantity": 1, "addons": [] }
]

Multidimensional arrays — arrays of arrays:

[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

Full Example

A complete table schema with nested objects and arrays:

{
"title": "iPhone 16 Pro",
"price": 999,
"inStock": true,
"specs": {
"weight": 199,
"tags": ["5G", "USB-C", "ProMotion"]
},
"variants": [
{ "color": "Desert Titanium", "storage": 256 },
{ "color": "Black Titanium", "storage": 512 }
]
}
Schema Editor — products table with nested specs and variants
Schema Editor — products table with nested specs and variants

Default Values

Primitive fields (string, number, boolean) must have a default value. Defaults serve two purposes:

  1. New rows start with valid data — no null fields
  2. Schema evolution — when you add a field to an existing table, all existing rows get the default value automatically
{ "type": "string", "default": "" }
{ "type": "number", "default": 0 }
{ "type": "boolean", "default": false }

Object and array fields don't require a default — they are initialized from their structure.

See Schema Evolution for more on how data transforms when schemas change.

Root Types

Most tables use type: "object" as the root — a record with named fields. But a row can also be:

Root array — e.g., a pricing table:

[
{ "from": 0, "to": 100, "pricePerUnit": 10.00 },
{ "from": 101, "to": 500, "pricePerUnit": 8.50 },
{ "from": 501, "to": 999999, "pricePerUnit": 6.00 }
]

Root primitive — e.g., a feature flag:

true
Root primitive — feature flags table with boolean values per row
Root primitive — feature flags table with boolean values per row

System Fields

System fields (id, createdAt, updatedAt, etc.) are stored at the database level, outside your JSON data. APIs return system fields alongside your data automatically — you don't need to add them to the schema.

You can optionally inject system fields into your JSON data via $ref if you want them inside the row body — at any nesting level and with any field name. This is purely for convenience; the platform doesn't force system fields into your schema.

Schema Editor — System fields submenu with id, versionId, createdId, createdAt, publishedAt, updatedAt, hash, schemaHash
Schema Editor — System fields submenu with id, versionId, createdId, createdAt, publishedAt, updatedAt, hash, schemaHash
{
"myId": "iphone-16",
"createdAt": "2026-03-15T10:30:00Z",
"title": "iPhone 16 Pro",
"meta": {
"created": "2026-03-15T10:30:00Z"
}
}

myId, createdAt, and meta.created are populated automatically by the platform.

Available system refs:

RefValue
urn:jsonschema:io:revisium:row-id-schema:1.0.0Row ID (string)
urn:jsonschema:io:revisium:row-created-id-schema:1.0.0Original creation ID
urn:jsonschema:io:revisium:row-version-id-schema:1.0.0Version ID
urn:jsonschema:io:revisium:row-created-at-schema:1.0.0Creation timestamp
urn:jsonschema:io:revisium:row-published-at-schema:1.0.0Publication timestamp
urn:jsonschema:io:revisium:row-updated-at-schema:1.0.0Last update timestamp
urn:jsonschema:io:revisium:row-hash-schema:1.0.0Content hash
urn:jsonschema:io:revisium:row-schema-hash-schema:1.0.0Schema hash

What's Next

Data modeling defines the structure. On top of it, you can add:

  • Foreign Keys — relationships between tables with referential integrity
  • Computed Fields — formula-based read-only fields (x-formula)
  • Files — S3 file attachments at any schema level
  • Schema Evolution — change types, add/remove fields with automatic data transforms