OpenAPI - Serializers
Serializers have the unique ability to transform the attributes and associations assigned to them into robust OpenAPI types. Dream and Psychic both work together to leverage the products of the types provided by serializers into the openapi schemas produced. This enables you to compose openapi types with ease, and will automatically interpret database-level types into fully-expanded OpenAPI types without any effort on your part, allowing you to get all of the OpenAPI types for your app out of the box without doing anything (unless your serializers need to deliver something more than what is in the database).
Automatic type inference
Serializers will automatically infer types provided to Attribute
, RendersOne
, and RendersMany
decorators, as long as the correct arguments are provided. For the Attribute decorator, this is as simple as providing the parent model class as the first argument:
Attribute type inference
class PetSerializer extends DreamSerializer {
@Attribute(Pet)
public name: DreamColumn<Pet>
}
Dream will automatically read the database types for Pet#name
, returning an OpenAPI type like:
schema: {
Pet: {
type: 'object',
required: ['name'],
properties: {
name: {
{ type: 'string', nullable: true }
}
}
}
}
We recommend that you utilize type inference where possible, since it will automatically respond to migrations to generate the most up-to-date types, leaving you with a completely hands-off approach to maintaining your openapi types.
Date inference
Unlike most javascript-based frameworks, Psychic makes a careful distinction between DateTime and CalendarDate, which it uses for datetimes and dates, respectively. Psychic will automatically instantiate instances of DateTime
and CalendarDate
as it reads postgres timestamp
or date
fields from database rows and instantiates model instances out of them, and will automatically convert them to iso8601
strings upon serializing to JSON, correctly delivering YYYY-MM-DD
format for date fields, while delivering the full iso8601
timestamp spec for date-time fields, including TZ information. In the OpenAPI layer, Psychic will automatically type dates and date-times respectively, like so:
class PetSerializer extends DreamSerializer {
@Attribute(Pet)
public createdOn: DreamColumn<Pet>
@Attribute(Pet)
public createdAt: DreamColumn<Pet>
}
schema: {
Pet: {
type: 'object',
required: ['createdOn', 'createdAt'],
properties: {
createdOn: {
{ type: 'string', format: 'date' },
},
createdAt: {
{ type: 'string', format: 'date-time' },
}
}
}
}
Associaiton type inference
With our RendersOne
and RendersMany
decorators, we provide nested serializer usage, without duplicating structures unnecessarily, like so:
class UserSerializer extends DreamSerializer {
@RendersMany(Post)
public posts: Post[]
@RendersOne(Post, { optional: true })
public latestPost: Post | null
}
which would produce something like:
schema: {
User: {
type: 'object',
required: ['posts', 'latestPost'],
properties: {
posts: {
type: 'array',
items: {
$ref: '#/components/schemas/Post'
}
}
latestPost: {
anyOf: [
{
$ref: '#/components/schemas/Post'
},
{ null: true }
]
}
}
},
Post: {
type: 'object',
required: ['id','body'],
properties: {
id: { type: 'string' },
body: { type: 'string', nullable: true },
}
}
}