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