ProtectedattributesProtecteddataProtectedpassthroughThe attribute name from the data object
Configuration options:
openapi - (required) OpenAPI schema definition for the attributeas - Rename the attribute key in the serialized output and OpenAPI shapedefault - Value to use when the attribute is undefinedprecision - Round decimal values to the specified number of decimal places (0–9)
during rendering; does not affect the OpenAPI shaperequired - Set to false to mark the attribute as optional in the OpenAPI schema;
when omitted, attributes are required by default, meaning undefined values will
serialize as nullThe serializer builder for method chaining
// Required OpenAPI schema
.attribute('email', {
openapi: { type: 'string', format: 'email' }
})
// With default value
.attribute('status', {
openapi: { type: 'string' },
default: 'active'
})
// Rename output key
.attribute('email', {
openapi: { type: 'string' },
as: 'userEmail'
})
// Round decimal to 2 places
.attribute('price', {
openapi: 'decimal',
precision: 2
})
// Mark as optional in OpenAPI (omitted from response when undefined)
.attribute('nickname', {
openapi: 'string',
required: false
})
Includes a computed value in the serialized output.
Executes a callback function to generate a custom attribute value.
The openapi option is always required since the return type cannot be inferred.
Unlike DreamSerializerBuilder's customAttribute, this version does not support as
or precision.
The attribute name for the computed value
Callback function that returns the computed value
Configuration options:
openapi - (required) OpenAPI schema definition for the computed valuedefault - Value to use when the callback returns undefinedflatten - When true, spreads the returned object's properties directly into the
parent serialized output instead of nesting them under name; the openapi option
should then define each flattened property individuallyrequired - Set to false to mark the attribute as optional in the OpenAPI schema;
when omitted, attributes are required by defaultThe serializer builder for method chaining
// Simple computed value
.customAttribute('fullName', () =>
`${user.firstName} ${user.lastName}`,
{ openapi: { type: 'string' } }
)
// Flattened object properties
.customAttribute('coordinates', () => ({ lat: 40.7, lng: -74.0 }), {
flatten: true,
openapi: {
lat: { type: 'number' },
lng: { type: 'number' }
}
})
Includes an attribute from a nested object in the serialized output.
Accesses targetName.name on the data object. The openapi option is always
required. When the target object or the delegated attribute is null/undefined,
the resolution order is:
default if provided → renders the default valuerequired: false → omits the key entirely from the rendered outputnulloptional and required are not aliases — they encode different things and can
be used together:
optional: true is an OpenAPI-only marker (no runtime effect). It declares
that the rendered value may be null. Use this when you want the key to always
be present but the value to be nullable in the schema.required: false affects both runtime and OpenAPI. At runtime, when the
resolved value is undefined, the key is omitted from the rendered output.
In OpenAPI, the field is marked as not required.The property name containing the target object
The attribute name within the target object
Configuration options:
openapi - (required) OpenAPI schema definition for the attributeas - Rename the attribute key in the serialized output and OpenAPI shape
(e.g., delegating 'profile', 'avatarUrl' with as: 'avatar' outputs the value
under avatar)default - Value to use when the target object or its attribute is null/undefinedoptional - Set to true to mark the value as nullable in the OpenAPI schema
(wraps the type in anyOf: [schema, { type: 'null' }]). OpenAPI-only — the
key is still rendered (as null)precision - Round decimal values to the specified number of decimal places (0–9)
during rendering; does not affect the OpenAPI shaperequired - Set to false to omit the key from the rendered output when the
resolved value is undefined, and to mark the field as not required in the
OpenAPI schemaThe serializer builder for method chaining
// Delegate to user.email
.delegatedAttribute('user', 'email', {
openapi: { type: 'string', format: 'email' }
})
// With default value for null target or attribute
.delegatedAttribute('profile', 'displayName', {
openapi: { type: 'string' },
default: 'Anonymous User'
})
// Rename the output key
.delegatedAttribute('profile', 'avatarUrl', {
openapi: 'string',
as: 'avatar'
})
Executes the serializer and returns the serialized output.
Processes all defined attributes, custom attributes, delegated attributes, and associations to produce the final serialized object.
Additional data to pass through to nested serializers (e.g., locale, current user context)
Rendering options for customizing the serialization process
The serialized object, suitable for JSON responses
Includes an array of associated objects in the serialized output.
For ObjectSerializer, explicit serializer configuration is always required since association schemas cannot be inferred from plain objects.
The association property name (should resolve to an array)
Configuration options:
as - Rename the association key in the serialized outputFor Dream associations:
dreamClass - The Dream model class, enabling serializer inference; when specified,
serializerKey may also be provided to select a specific registered serializerserializer - Provide an explicit serializer functionFor ViewModel associations:
viewModelClass + optional serializerKeyserializerFor non-Dream/non-ViewModel associations:
serializer is requiredThe serializer builder for method chaining
// With explicit serializer function
.rendersMany('articles', { serializer: ArticleSerializer })
// With Dream class reference and serializer key
.rendersMany('posts', {
dreamClass: Post,
serializerKey: 'summary'
})
// With ViewModel class reference
.rendersMany('comments', {
viewModelClass: CommentViewModel,
serializer: CommentViewModelSerializer
})
// Rename output key
.rendersMany('articles', { serializer: ArticleSerializer, as: 'posts' })
Includes a single associated object in the serialized output.
For ObjectSerializer, explicit serializer configuration is always required since association schemas cannot be inferred from plain objects.
The association property name
Configuration options:
as - Rename the association key in the serialized outputflatten - When true, spreads the rendered association's attributes directly into
the parent serialized output instead of nesting them under name. Be aware of
attribute shadowing: if the parent and flattened association share attribute names
(e.g., id), the flattened association's values overwrite the parent'soptional - When true, allows the association to be null/missing without causing
an OpenapiResponseValidationFailure during Psychic controller unit specs. By default,
rendersOne expects the association to be present (mirroring the optional option on
@deco.BelongsTo). Set this to true when the association is genuinely nullableFor Dream associations:
dreamClass - The Dream model class, enabling serializer inference; when specified,
serializerKey may also be provided to select a specific registered serializerserializer - Provide an explicit serializer functionFor ViewModel associations:
viewModelClass + optional serializerKeyserializerFor non-Dream/non-ViewModel associations:
serializer is requiredOptionalas?: stringRename the association key in the serialized output.
Optionalflatten?: booleanIf true, the rendered association's attributes are merged directly into
the parent object instead of being nested under the association key.
Optionaloptional?: booleanIf true, the association is treated as nullable in the OpenAPI spec,
allowing null when the association doesn't resolve. Set this for
associations that may not exist.
The serializer builder for method chaining
// With explicit serializer function
.rendersOne('owner', { serializer: CustomOwnerSerializer })
// With Dream class reference and serializer key
.rendersOne('creator', {
dreamClass: User,
serializerKey: 'summary'
})
// Allow null association
.rendersOne('approver', { serializer: UserSerializer, optional: true })
// Flatten into parent object
.rendersOne('profile', { serializer: ProfileSerializer, flatten: true })
Includes an attribute from the data object in the serialized output.
For ObjectSerializer, the
openapioption is always required since type inference is not available for plain objects or ViewModels.