Overview
Dream serializers translate data into json, usually for returning as an API response. They also participate in Psychic’s automatic OpenAPI generation.
-
DreamSerializer
andObjectSerializer
: All serializers will return the result of calling DreamSerializer (for serializing Dream models) or ObjectSerializer (for serializing view models or simple javascript objects). DreamSerializer leverages Dream’s knowledge of the database schema and associations to automatically determine OpenAPI shape. ObjectSerializer requires the OpenAPI shape of each attribute to be provided. -
Fluent API: The structure is defined by chaining calls to
.attribute()
,.customAttribute()
,.delegatedAttribute()
,.rendersOne()
, and.rendersMany()
. -
OpenAPI Generation: Serializers feed into Psychic’s automatic OpenAPI gneration, thereby keeping API documentation consistent with its implementation.
-
Flexibility: Each model can have multiple serializers, so different data can be rendered in different contexts (e.g.
index
vs.show
endpoints). -
Synchronous by Design: Dream serializers are intentionally synchronous. This prevents accidental introduction of N+1 query problems during serialization.
Example
Here's an example serializer from the BearBnB demo app:
import { DreamSerializer } from '@rvoh/dream'
import { LocalesEnum } from '../../types/db.js'
import i18n from '../../utils/i18n.js'
import Place from '../models/Place.js'
export const PlaceSummarySerializer = (place: Place) =>
DreamSerializer(Place, place).attribute('id').attribute('name')
export const PlaceSerializer = (place: Place) =>
PlaceSummarySerializer(place).attribute('style').attribute('sleeps').attribute('deletedAt')
export const PlaceSummaryForGuestsSerializer = (place: Place) =>
DreamSerializer(Place, place)
.attribute('id')
.delegatedAttribute('currentLocalizedText', 'title', { openapi: 'string' })
export const PlaceForGuestsSerializer = (place: Place, passthrough: { locale: LocalesEnum }) =>
PlaceSummaryForGuestsSerializer(place)
.customAttribute('style', () => i18n(passthrough.locale, `places.style.${place.style}`), {
openapi: 'string',
})
.attribute('sleeps')
.delegatedAttribute('currentLocalizedText', 'title', { openapi: 'string' })
.rendersMany('rooms', { serializerKey: 'forGuests' })
This documentation will guide you through defining attributes, handling associations, generating serializers, and using them to render data and produce OpenAPI schemas.