Creating A Schema

Schemas in Routier define the structure and behavior of your data entities. The schema builder provides a fluent, type-safe API for creating robust data schemas.

Quick Navigation

Basic Schema Definition

import { s } from "@routier/core/schema";

// Basic schema definition
const userSchema = s
    .define("users", {
        id: s.string().key().identity(),
        email: s.string().distinct(),
        name: s.string(),
        createdAt: s.date().default(() => new Date()),
    })
    .compile();

Schema Builder API

The s object provides the main entry point for schema creation:

Core Functions

  • s.define(collectionName, schema) - Creates a schema definition
  • s.number<T>() - Number property with optional literal constraints
  • s.string<T>() - String property with optional literal constraints
  • s.boolean<T>() - Boolean property
  • s.date<T>() - Date property
  • s.array(schema) - Array property containing other schemas
  • s.object(schema) - Object property with nested schema

Literal Type Constraints

You can constrain properties to specific literal values:

import { s } from "@routier/core/schema";

// Literal type constraints
const statusSchema = s.define("orders", {
    id: s.string().key().identity(),
    status: s.string("pending", "processing", "completed", "cancelled"),
    priority: s.number(1, 2, 3, 4, 5),
    isActive: s.boolean(),
}).compile();

Property Modifiers

Each schema type supports a set of modifiers that can be chained together:

Core Modifiers

import { s } from "@routier/core/schema";

// Core modifiers
const productSchema = s.define("products", {
    id: s.string().key().identity(),
    name: s.string().optional().nullable(),
    price: s.number().default(0),
    description: s.string().readonly(),
    category: s.string().distinct(),
    createdAt: s.date().default(() => new Date()),
}).compile();

Serialization Modifiers

import { s } from "@routier/core/schema";

// Serialization modifiers
const configSchema = s.define("config", {
    id: s.string().key().identity(),
    settings: s.object({
        theme: s.string(),
        notifications: s.boolean(),
    }).serialize((obj) => JSON.stringify(obj))
        .deserialize((str) => JSON.parse(str)),
    metadata: s.array(s.string()).serialize((arr) => arr.join(","))
        .deserialize((str) => str.split(",")),
}).compile();

Array and Object Modifiers

import { s } from "@routier/core/schema";

// Array and object modifiers
const companySchema = s.define("companies", {
    id: s.string().key().identity(),
    name: s.string(),
    address: s.object({
        street: s.string(),
        city: s.string(),
        zipCode: s.string(),
    }).optional(),
    departments: s.array(s.string()).default([]),
    employees: s.array(s.object({
        name: s.string(),
        role: s.string(),
        startDate: s.date(),
    })).optional(),
}).compile();

Complete Example

import { s } from "@routier/core/schema";

// Complete example with all features
const blogPostSchema = s.define("blogPosts", {
    id: s.string().key().identity(),
    title: s.string().distinct(),
    content: s.string(),
    author: s.string(),
    tags: s.array(s.string()).default([]),
    status: s.string("draft", "published", "archived").default("draft"),
    publishedAt: s.date().optional(),
    metadata: s.object({
        views: s.number().default(0),
        likes: s.number().default(0),
        comments: s.array(s.object({
            author: s.string(),
            content: s.string(),
            createdAt: s.date().default(() => new Date()),
        })).default([]),
    }).default({}),
    createdAt: s.date().default(() => new Date()),
    updatedAt: s.date().default(() => new Date()),
}).compile();

Modifier Chaining

Modifiers can be chained in any order, but it’s recommended to follow a logical pattern:

import { s } from "@routier/core/schema";

// Modifier chaining examples
const chainedSchema = s.define("examples", {
    // Recommended order: type -> constraints -> behavior -> defaults
    id: s.string().key().identity(),
    email: s.string().distinct().optional(),
    age: s.number(18, 19, 20, 21).default(18),
    status: s.string("active", "inactive").default("active").readonly(),

    // Complex chaining
    profile: s.object({
        bio: s.string().optional().nullable(),
        avatar: s.string().optional(),
    }).optional().serialize((obj) => JSON.stringify(obj))
        .deserialize((str) => JSON.parse(str)),
}).compile();

Compiling Schemas

Always call .compile() at the end to create the final schema:

import { s } from "@routier/core/schema";

// Compiling schemas
const userSchema = s.define("users", {
    id: s.string().key().identity(),
    name: s.string(),
    email: s.string().distinct(),
}).compile();

// The compiled schema is ready to use
// You can now use it with collections, type inference, etc.
type User = typeof userSchema;

Next Steps