Skip to content

Latest commit

 

History

History
137 lines (101 loc) · 4.35 KB

File metadata and controls

137 lines (101 loc) · 4.35 KB

Modifiers

Overview

Modifiers from @antelopejs/interface-database-decorators work automatically with the Data API. Modifiers such as @Hashed or @Encrypted transform data transparently during read and write operations without any additional configuration in the data controller.

Some modifiers require a runtime parameter (for example, a locale key for localization). The @ModifierKey decorator bridges this gap by mapping a controller field to a modifier's runtime key.

The @ModifierKey Decorator

Use @ModifierKey when a modifier needs a runtime value that varies per request. The decorator associates a controller field with a specific modifier class. The field's value at request time is passed to the modifier during lock and unlock operations.

import { ModifierKey } from "@antelopejs/interface-data-api/metadata";

Signature

@ModifierKey(modifierClass: typeof ContainerModifier<any>)
Parameter Description
modifierClass The modifier class that requires a runtime key (e.g., LocalizationModifier)

Example: Localized Content

The LocalizationModifier requires a locale identifier to determine which translation to store or retrieve. Use @ModifierKey to supply this value from an HTTP header.

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

@RegisterTable("content")
class Content extends Table.with(LocalizationModifier) {
  @Index({ primary: true })
  @Field("string")
  declare _id: string;

  @Localized()
  @Field("string")
  declare title: string;

  @Localized()
  @Field("string")
  declare description: string;
}

class ContentModel extends BasicDataModel(Content, "content") {}

@RegisterDataController()
class ContentAPI extends DataController(
  Content,
  DefaultRoutes.All,
  Controller("/content"),
) {
  @ModelReference()
  @Model(ContentModel, "my-database")
  declare contentModel: ContentModel;

  @Parameter("x-content-language", "header")
  @ModifierKey(LocalizationModifier)
  declare language: string;

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

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

How It Works

  1. The HTTP request includes the header x-content-language: fr.
  2. The language property receives the value "fr".
  3. During write operations, the modifier uses "fr" as the key to store the localized value.
  4. During read operations, the modifier uses "fr" to retrieve the correct localized value.

Example request:

POST /content/new
x-content-language: fr
Content-Type: application/json

{
  "title": "Titre en francais",
  "description": "Description en francais"
}

The data is stored under the "fr" locale key. A subsequent request with x-content-language: en accesses different localized values for the same record.

Note: Most modifiers (such as @Hashed and @Encrypted) do not require @ModifierKey. Only modifiers that need a runtime parameter per request require this decorator.

Integration with Other Features

Foreign Keys

Modifiers work automatically with foreign key relationships. When the Data API resolves foreign records, modifier-protected fields on those records are properly unlocked during retrieval. See the foreign keys documentation for details.

Filters

When filtering modifier-protected fields, custom filter functions receive the unlocked (transformed) value through the proxy parameter. This ensures filters operate on the correct data. See the filters documentation for details.

Learn More

For the full list of available modifiers and instructions on creating custom ones, see the @antelopejs/interface-database-decorators documentation.

Next Steps

See the joined fields documentation to learn how to flatten a remote field onto rows for native sorting and filtering.