Skip to content

Latest commit

 

History

History
128 lines (99 loc) · 5.53 KB

2.data-controllers.md

File metadata and controls

128 lines (99 loc) · 5.53 KB
title Data controllers
description The DataController function, the RegisterDataController decorator, and the parts every data controller declares.
mode reference

Overview

A data controller connects a database table to a set of API endpoints and exposes the table fields you declare on the class. The DataController function returns a base class built from three parts: the table class, the route definitions and the controller base that holds the endpoint path.

Create a data controller

DataController takes three arguments: the table class, a route definition object, and a controller base with the endpoint path.

The example uses the myapp schema and the my-database instance. Import the table declaration and await RegisterSchema("myapp") in the declaring module before it serves requests. Your database setup provisions the named instance.

import { Controller } from "@antelopejs/interface-api";
import {
  DataController,
  DefaultRoutes,
  RegisterDataController,
} from "@antelopejs/interface-data-api";
import {
  Access,
  AccessMode,
  Listable,
  ModelReference,
} from "@antelopejs/interface-data-api/metadata";
import {
  BasicDataModel,
  Field,
  Model,
  RegisterTable,
  Table,
} from "@antelopejs/interface-database-decorators";

@RegisterTable("users", "myapp")
class User extends Table {
  @Field("string")
  declare _id: string;

  @Field("string")
  declare email: string;

  @Field("number")
  declare age: number;
}

class UserModel extends BasicDataModel(User, "users") {}

@RegisterDataController()
class UserAPI extends DataController(
  User,
  DefaultRoutes.All,
  Controller("/users"),
) {
  @ModelReference()
  @Model(UserModel, "my-database")
  declare userModel: UserModel;

  @Listable()
  @Access(AccessMode.ReadOnly)
  declare _id: string;

  @Listable()
  @Access(AccessMode.ReadWrite)
  declare email: string;

  @Access(AccessMode.ReadWrite)
  declare age: number;
}

DataController signature

function DataController<
  C extends Class,
  P extends DataControllerDef = DataControllerDef,
  Base extends ControllerClass = ControllerClass,
>(
  tableClass: C,
  def: P,
  base: Base,
): Class<ExtractDefCallbacks<P> & { table: InstanceType<C> }> & Base;
Parameter Description
tableClass The table class decorated with @RegisterTable. DataController throws Non-existent Database Schema when the table's schema is not registered, and Unregistered Database Table when the schema does not hold the table.
def An object that maps endpoint names to route callbacks. Use DefaultRoutes.All for the five CRUD routes, or pass a subset or custom routes.
base The controller base, usually Controller("/path") from @antelopejs/interface-api. Its location is the URL prefix of every endpoint.

The returned class extends base. Its prototype holds one method per key of def, and its instances declare a table field typed by the table class.

Required components

Every data controller declares these four parts.

  1. Table class. A database table decorated with @RegisterTable, which defines the schema.
  2. Route definitions. The operations to expose. Use DefaultRoutes.All or a custom selection.
  3. Controller base. The URL path prefix, created with Controller("/path").
  4. Model reference. A property decorated with @ModelReference() that holds a database model instance. The model runs the database operations (insert, get, update and delete). A controller derived from another data controller (for example Controller("/path", ParentController)) inherits its model reference unless it declares its own.

The @RegisterDataController decorator

Apply @RegisterDataController() to the class to finish the controller setup. For each route of the definition, the decorator applies the route's parameter decorators, registers a prefix route that records the route entry on the request context, and registers the route method as the handler at <controller location>/<endpoint>.

Field declarations

The fields you declare on the data controller class decide which table fields the API exposes. Each field takes decorators that set its behaviour:

  • @Access sets read and write permissions.
  • @Listable includes the field in list responses.
  • @Mandatory requires the field on specific operations.
  • @Validator attaches a validation function.
  • @Foreign declares a foreign key relationship.
  • @Joined flattens a scalar field from another table onto the row.
  • @Computed adds a value the database computes for each row.
  • @Filter enables filtering on the field.
  • @Sortable allows sorting by the field.

The Data API ignores a field without an access mode. Such a field never appears in responses and never accepts input. @Access gives a field its mode, and @Joined and @Computed make their field read-only.

Next steps

The routes page lists the available routes and how to customize them.