[data-reveal]{opacity:1!important;transform:none!important}
Database Decorators

Parameter Decoration

The Database Decorators package provides the Model decorator for injecting data model instances into API controller methods. This decorator integrates with the @antelopejs/interface-api package's parameter provider system.

The Model Decorator

The Model decorator injects a cached model instance. It can be used as either a parameter decorator or a property decorator.

Static Instance ID

Pass a fixed instance ID to bind the model to a specific schema instance:

import { Controller, Get } from "@antelopejs/interface-api";
import { Model } from "@antelopejs/interface-database-decorators";
import { UserModel } from "./user.model";

class UsersController extends Controller("/users") {
  @Get()
  async listUsers(@Model(UserModel, "main") userModel: InstanceType<typeof UserModel>) {
    return await userModel.getAll();
  }
}

Dynamic Instance ID

Pass a callback function to determine the instance ID at request time. The callback receives the request context:

import { Controller, Get, Parameter } from "@antelopejs/interface-api";
import { Model } from "@antelopejs/interface-database-decorators";
import { UserModel } from "./user.model";

class MultitenantController extends Controller("/tenants") {
  @Get("/:tenantId/users")
  async getTenantUsers(
    @Parameter("tenantId") tenantId: string,
    @Model(UserModel, (ctx) => `tenant-${ctx.params.tenantId}`) userModel: InstanceType<typeof UserModel>,
  ) {
    return await userModel.getAll();
  }
}

Property Decoration

The Model decorator also works as a property decorator. The model is initialized when the controller handles a request:

import { Controller, Get, Parameter } from "@antelopejs/interface-api";
import { Model } from "@antelopejs/interface-database-decorators";
import { UserModel } from "./models";

class UsersController extends Controller("/users") {
  @Model(UserModel, "main")
  private userModel!: InstanceType<typeof UserModel>;

  @Get()
  async listUsers() {
    return await this.userModel.getAll();
  }

  @Get("/:id")
  async getUser(@Parameter("id") id: string) {
    return await this.userModel.get(id);
  }
}

Model Caching

The Model decorator uses GetModel internally, which caches model instances by class and instance ID. Multiple decorators referencing the same model class and instance ID share a single instance:

import { GetModel } from "@antelopejs/interface-database-decorators";

// These return the same instance
const model1 = GetModel(UserModel, "main");
const model2 = GetModel(UserModel, "main");

// This returns a different instance
const model3 = GetModel(UserModel, "other");

Combine with API Decorators

Model decorators compose naturally with other API decorators for building complete CRUD controllers:

import { Controller, Get, Post, Put, Delete, RawBody, Parameter } from "@antelopejs/interface-api";
import { Model } from "@antelopejs/interface-database-decorators";
import { UserModel } from "./user.model";

class UsersController extends Controller("/users") {
  @Get()
  async list(@Model(UserModel, "main") model: InstanceType<typeof UserModel>) {
    return await model.getAll();
  }

  @Get("/:id")
  async get(
    @Parameter("id") id: string,
    @Model(UserModel, "main") model: InstanceType<typeof UserModel>,
  ) {
    return await model.get(id);
  }

  @Post()
  async create(
    @RawBody() body: Buffer,
    @Model(UserModel, "main") model: InstanceType<typeof UserModel>,
  ) {
    const data = JSON.parse(body.toString());
    return await model.insert(data);
  }

  @Put("/:id")
  async update(
    @Parameter("id") id: string,
    @RawBody() body: Buffer,
    @Model(UserModel, "main") model: InstanceType<typeof UserModel>,
  ) {
    const data = JSON.parse(body.toString());
    return await model.update(id, data);
  }

  @Delete("/:id")
  async remove(
    @Parameter("id") id: string,
    @Model(UserModel, "main") model: InstanceType<typeof UserModel>,
  ) {
    return await model.delete(id);
  }
}

Custom Parameter Providers

For more complex injection logic, create custom parameter providers using the core API:

import { SetParameterProvider } from "@antelopejs/interface-api";
import { GetModel } from "@antelopejs/interface-database-decorators";
import { MakeParameterAndPropertyDecorator } from "@antelopejs/interface-core/decorators";

const CustomModel = MakeParameterAndPropertyDecorator(
  (target, key, index, modelClass, resolver) => {
    SetParameterProvider(target, key, index, (ctx) => {
      const instanceId = resolver(ctx);
      return GetModel(modelClass, instanceId);
    });
  },
);