Data Modeling
Objects, fields, relationships, validation, CEL formulas, and a compiled query AST — the ObjectQL layer every other module builds on.
Data Modeling
Every ObjectStack application starts here: you declare objects (business entities), their fields, relationships, and validation rules as typed metadata, and the platform derives the database schema, REST API, permission surface, and UI from that single definition. This module is the practical documentation for the ObjectQL layer — the Data Protocol specified normatively in the ObjectQL spec.
A real object definition looks like this (from the CRM example app):
import { ObjectSchema, Field } from '@objectstack/spec/data';
export const Lead = ObjectSchema.create({
name: 'crm_lead',
label: 'Lead',
pluralLabel: 'Leads',
icon: 'funnel',
description: 'An inbound prospect not yet qualified as an opportunity.',
fields: {
name: Field.text({ label: 'Lead Name', required: true, searchable: true, maxLength: 200 }),
email: Field.email({ label: 'Email', searchable: true }),
phone: Field.phone({ label: 'Phone' }),
company: Field.text({ label: 'Company', searchable: true, maxLength: 200 }),
},
});That one definition is enough to get a persisted table, CRUD + query endpoints, permission checks, and generated list views and forms.
What the data layer actually gives you
- A full spectrum of field types — from
text,currency, andlookup/master_detailrelationships toformula,summary,signature, andvector(with index config for AI embeddings). See the Field Types gallery. - Validation as metadata — required/format rules, CEL script validation with access to
previous.<field>, uniqueness via indexes, and severity levels — enforced identically in API, UI, and automation. - CEL expressions — formula fields and computed defaults share one expression language (Expressions).
- A compiled query AST — queries are JSON documents validated against the protocol, then compiled by a driver into native queries with joins, aggregations, window functions, HAVING, and subqueries. The query cheat sheet covers the syntax; the spec is normative.
- Four database drivers in this repo —
driver-sql(PostgreSQL / MySQL / SQLite via Knex),driver-mongodb,driver-memory(in-memory, for tests and demos), anddriver-sqlite-wasm(SQLite in the browser / WebContainers). The same model runs unchanged on any of them. - External datasource federation — introspect an existing external database, import selected tables into the catalog, and query them alongside native objects (External Datasources).
What's in this module
Schema Design
End-to-end guide: designing objects, field groups, and real-world schemas
Objects
Object metadata: definition, options, and API operations
Fields
Field metadata and configuration
Field Types
Gallery of every field type with examples
Relationships & Lookups
Lookup, master-detail, and cross-object modeling
Validation
Validation metadata and CEL rule authoring
Expressions (CEL)
Formula fields and computed logic
Queries
Query syntax quick reference
Database Indexing
Index configuration and performance
Seed Data & Fixtures
Ship demo and reference data with your app
External Datasources
Federate external databases into the model
Database Drivers
Configure SQL, MongoDB, in-memory, and WASM drivers
Analytics Datasets
Model datasets for dashboards and reports
Related
- Spec: ObjectQL — Schema, Query Syntax, Type System
- Schema reference: Data
- Neighbors: record access rules live in Permissions & Identity; reacting to data changes lives in Automation; presenting records lives in UI Engine.