Skip to main content

ApiField

Package: @opra/common

@ApiField() is a property decorator that declares a field on a ComplexType class. It records the field's type, constraints, and serialization behavior in the OPRA type registry. Fields are used for request body decoding, response encoding, validation, and filter/sort declarations.


Usage

import { ComplexType, ApiField } from '@opra/common';

@ComplexType()
export class Customer {
@ApiField({ keyField: true })
declare _id: number;

@ApiField({ required: true })
declare email: string;

@ApiField({ readonly: true })
declare createdAt: Date;

@ApiField({ deprecated: 'Use email instead' })
declare username: string;
}

OPRA infers the field type from TypeScript's design:type metadata automatically. Use the type option to override or to specify a type that cannot be inferred (e.g., union or enum types).


Options

OptionTypeDescription
typestring | TypeExplicit field type. Inferred from TypeScript metadata if omitted.
descriptionstringHuman-readable description of the field.
requiredbooleanField must be present in input.
readonlybooleanField is excluded from write operations (input decoding).
writeonlybooleanField is excluded from read operations (output encoding).
defaultanyDefault value applied when the field is absent.
fixedanyConstant value — any other value fails validation.
exclusivebooleanField is omitted from results unless the client explicitly requests it via an include parameter.
keyFieldbooleanMarks this field as the entity's primary key.
isArraybooleanField holds an array of the declared type.
deprecatedboolean | stringMarks the field as deprecated. Pass a string for a deprecation message.
localizationbooleanField supports locale-specific values.
scopePattern(string | RegExp) | (string | RegExp)[]Restricts serialization of this field to matching scopes. See Scope filtering.

Explicit type

When TypeScript cannot infer the type (array fields, enum types, forward references), pass the type explicitly:

import { ComplexType, ApiField, EnumType, ArrayType } from '@opra/common';

const StatusType = EnumType(['active', 'passive'] as const);

@ComplexType()
export class Customer {
// Explicit enum type
@ApiField({ type: StatusType })
declare status: string;

// Array field — TypeScript infers Array but not the element type
@ApiField({ type: String, isArray: true })
declare tags: string[];
}

Scope filtering

scopePattern limits when a field is included in serialization to requests that match the given scope(s). This is useful for fields that should only appear in specific contexts (e.g., admin responses).

@ApiField({ scopePattern: 'admin' })
declare internalNotes: string;

@ApiField({ scopePattern: ['admin', /^reporting.*/] })
declare costPrice: number;

The adapter's scope option (set at construction time) is matched against each field's scopePattern before serialization.


Scope override

Use .Override() chained on @ApiField() to apply different field settings for a specific scope without changing the default behavior. This is useful for making a field required in create but optional in patch operations.

@ApiField({ required: true })
.Override('patch', { required: false })
declare email: string;

@ApiField({ readonly: false })
.Override('admin', { readonly: true })
declare sensitiveField: string;
ApiField.Override(
scopePattern: (string | RegExp) | (string | RegExp)[],
options: Omit<ApiField.Options, 'isArray' | 'type' | 'scopePattern'>
): ApiFieldDecorator

Multiple .Override() calls can be chained on the same field.


ComplexType · EnumType · OmitType / PickType / PartialType / RequiredType