Schema
Schemas are optional. A schema does two independent jobs: it validates every write, and it declares which fields get indexes. Collections without a schema accept any array data.
$schema = Schema::collection('posts')
->string('slug')->unique()
->string('status')->index()
->int('publishedAt')->range()
->bool('featured')
->required(['slug', 'status']);
$posts = new DocStore($root, 'posts', schema: $schema);The schema's collection name must match the store's collection name; construction throws otherwise. Passing the schema to the constructor also syncs the declared indexes immediately.
Validation rules
requiredfields must be present in the written data. Presence is what is checked: an explicitnullsatisfies a required field.- Typed fields are checked only when present and non-null. A
stringfield rejects anintvalue; afloatfield accepts bothfloatandint. mixedfields accept anything and are useful to mark a field as required or indexed without constraining its type.- Fields not declared in the schema are unrestricted.
A failed validation throws a StorageException before anything is written.
Field types and flags
Supported types: string, int, float, bool, mixed.
Flags per field: index() (equality index), unique() (uniqueness enforced
at write time), range() (ordered index for gt/lt/between/prefix and
ordered range queries), and required().
Schema changes
Indexes are synced when the store is constructed. If a schema change alters the declared index set, the index manifest changes and the affected indexes are rebuilt from the existing records; validation rule changes apply to future writes only and never rewrite stored records.
The same Schema object can be reused to map typed columns in a
SQL mirror, including for collections whose store does
not itself use the schema.