Define tables and work with models
Overview
Use @antelopejs/interface-database-decorators to describe tables with TypeScript classes and work with converted records through models. It builds on AQL (@antelopejs/interface-database) and adds field modifiers and API model injection.
From a table class to a stored record
- Describe the table. Extend
Table, declare fields and indexes, and register the class with@RegisterTable("users", "myapp"). See table definitions. - Bind the schema. Import the table declarations, then call
await RegisterSchema("myapp")from their declaring module. This requires a configured database provider and can provision tables and insert fixtures; it is not a read-only metadata operation. - Create the model. Use
BasicDataModel(User)and aSchemaInstance, orGetModelafter the table has been bound. See data models. - Write and read through the model. Model operations apply conversion and modifier events. Use
model.tablewhen you need to compose an AQL query yourself.
Keep schema IDs and instance IDs distinct: myapp identifies the table definitions; an instance ID selects the database instance used by a model. A table class without a schema binding cannot be resolved by GetModel.
Save and retrieve a note
In a module with a configured database provider, import this declaration before calling tryNote() during initialization. Use a disposable development database: RegisterSchema provisions the schema, and insert writes data.
import {
BasicDataModel,
Field,
GetModel,
RegisterSchema,
RegisterTable,
Table,
} from "@antelopejs/interface-database-decorators";
@RegisterTable("notes", "notes-demo")
class Note extends Table {
@Field("string")
declare title: string;
}
class NoteModel extends BasicDataModel(Note) {}
export async function tryNote() {
await RegisterSchema("notes-demo");
const notes = GetModel(NoteModel);
const [id] = await notes.insert({ title: "Learn models" });
const saved = await notes.get(id);
if (!saved) throw new Error("The inserted note was not found");
return saved.title; // "Learn models"
}
The model uses the default instance of the schema bound to Note. Keep the inserted ID when extending this exercise with update or delete; each successful run inserts a new note. In an application, register the schema once during initialization rather than on each request.
Choose the layer for your task
| Task | Layer | Important boundary |
|---|---|---|
| Describe storage fields and indexes | Table definitions | Declaring a class is separate from registering its schema. |
| Encrypt, hash, or localize fields | Table modifiers | Conversion events determine when transformations run. |
| Read or write converted records | Data models | Reads return converted records, not chainable queries. |
| Select a model in an HTTP request | Parameter decoration | The instance ID selects a binding; it does not authorize access. |
Start without modifiers until the schema and model work together. Add validation explicitly: string-token @Field declarations describe storage, while codec validation requires codecs and the model's validation options.
Dependencies
This package depends on the following:
- @antelopejs/interface-database - The underlying database query interface (AQL)
- @antelopejs/interface-api - API controller integration for parameter decoration
- @antelopejs/interface-core - Core decorator utilities
- reflect-metadata - Metadata reflection for TypeScript decorators
- randomstring - Random string generation for hash salts
Documentation
- Table Definitions - Define database tables with the
Tableclass,Indexdecorator, andFixturedecorator - Table Modifiers - Apply encryption, hashing, and localization modifiers to table fields, or create custom modifiers
- Data Models - Create data models with
BasicDataModelfor CRUD operations and data conversion - Parameter Decoration - Inject model instances into API controller methods with the
Modeldecorator
Database Catalog
Use @antelopejs/interface-database-catalog to discover relations, inspect their structure, and profile aggregate characteristics before mapping an existing database into an application. The catalog describes a provider's connection; it does not open a new connection, register tables, or return raw records.
Table Definitions
The Database Decorators package provides a class-based approach to defining database tables. You extend the Table base class, declare each field with TypeScript's declare keyword and the @Field decorator, and use further decorators to configure indexes, relations, and initial data.