[data-reveal]{opacity:1!important;transform:none!important}
Data API

Filters

Overview

The @Filter decorator adds filtering capabilities to list endpoints. Filters allow clients to narrow down results using query parameters. The module provides a default filter with standard comparison operators and supports custom filter functions for advanced logic.

Basic Usage

Default Filter

Apply @Filter() without arguments to enable standard comparison filtering on a field.

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

@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)
  @Filter()
  declare age: number;

  @Listable()
  @Access(AccessMode.ReadWrite)
  @Filter()
  declare isActive: boolean;
}

Query Parameter Format

Filters are applied through query parameters using the following format:

filter_<fieldName>=<value>
filter_<fieldName>=<operator>:<value>

When no operator is specified, eq (equal) is used by default.

Comparison Operators

OperatorDescription
eqEqual to (default)
neNot equal to
gtGreater than
geGreater than or equal to
ltLess than
leLess than or equal to

Examples

Retrieve users older than 30:

GET /users/list?filter_age=gt:30

Retrieve active users:

GET /users/list?filter_isActive=true

Combine multiple filters (users under 25 who are active):

GET /users/list?filter_age=lt:25&filter_isActive=true

Custom Filters

For filtering logic beyond simple comparisons, pass a custom filter function to @Filter.

Filter Function Signature

type FilterFunction<T, U> = (
  context: RequestContext & { this: T },
  proxy: ValueProxy<any>,
  key: string,
  value: string,
  mode: "eq" | "ne" | "gt" | "ge" | "lt" | "le",
  row: ValueProxy<U>,
) => ValueProxyOrValue<boolean>;
ParameterDescription
contextThe request context, extended with this referencing the controller instance
proxyA ValueProxy representing the field value with modifier transformations applied (e.g., decrypted, localized)
keyThe field name being filtered
valueThe filter value from the query parameter
modeThe comparison operator from the query parameter
rowThe full database row as a ValueProxy

Example: Pattern Matching Filter

function filterByEmailDomain(
  context: RequestContext,
  proxy: ValueProxy<any>,
  key: string,
  value: string,
  mode: string,
  row: ValueProxy<Record<string, any>>,
) {
  return proxy.match(`@${value}$`);
}

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

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

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

Query for users with Gmail addresses:

GET /users/list?filter_email=gmail.com

The useIndex Parameter

The @Filter decorator accepts an optional second parameter, useIndex, that controls whether the filter can use a database index for optimized lookups.

@Filter(undefined, true)   // Default filter with index optimization
declare status: string;

@Filter(customFilter, false) // Custom filter without index optimization
declare name: string;

When useIndex is not specified:

  • Default filters (no custom function) automatically use the index if the field has one.
  • Custom filters default to no index usage.

Index-optimized filters with an eq operator perform an indexed lookup instead of a full table scan, which significantly improves performance on large datasets.

Modifier Integration

The proxy parameter in custom filter functions provides the field value after modifier transformations have been applied. For example, if a field uses an encryption modifier, proxy contains the decrypted value. This ensures filters work correctly with modifier-protected data.

For raw database values, use the row parameter and access the field directly.