Skip to main content

Serialization

Introduction

Serialization implementation provides partial implementations for serializer and deserializer dependencies.

Implementations

makeDeserializerWith

This partial implementation of the deserializer will produce instances from a generic record object.

It handles multiple features, such as:

  • Deduplicate records by identifier to avoid deserializing the same record multiple times.
  • Interact with the cache (if configured) to keep only one instance alive for one record.
  • Resolve model to deserialize record to automatically from context, relations and configuration.
  • Use model's properties aliases and value transformers.
  • Run the models' retrieved hook for each deserialized instance.

Usage

import { makeDeserializerRecordFactory, makeDeserializerWith } from '@foscia/serialization';

const deserializer = makeDeserializerWith({
extractData: (data) => ({
records: data as Arrayable<Record<string, any>> | null,
}),
createRecord: makeDeserializerRecordFactory(
(record) => record,
(record, { key }) => record[key],
(record, { key }) => record[key],
),
});

const { instances } = await deserializer.deserialize(data, {
/* ...context */
});

Configuration

NameTypeDescription
extractData(data: Data, context: {}) => Awaitable<Extract>Extract records contained in data and other useful data for deserialization.
createRecordDeserializerRecordFactory<Record, Data, Deserialized, Extract>Create a deserializer record object which provides identity and values pulling.
createData(instances: ModelInstance[], extract: Extract, context: {}) => Awaitable<Deserialized>Create deserialized instances wrapper object which might contain other data. Default to no additional data provided.
shouldDeserialize(deserializerContext: DeserializerContext<Record, Data, Deserialized>) => Awaitable<boolean>Check if an instance attribute or relation should be deserialized or not. Default to value not undefined.
deserializeKey(deserializerContext: DeserializerContext<Record, Data, Deserialized>) => Awaitable<string>Deserialize an instance attribute or relation key. Default to key aliasing and normalization.
deserializeAttribute(deserializerContext: DeserializerContext<Record, Data, Deserialized, ModelAttribute>) => Awaitable<unknown>Deserialize an instance attribute value. Default to use of attribute transformer.
deserializeRelated(deserializerContext: DeserializerContext<Record, Data, Deserialized, ModelRelation>, related: DeserializerRecord<Record, Data, Deserialized>, instancesMap: DeserializerInstancesMap) => Awaitable<unknown>Deserialize an instance relation's related instance(s). Default to instance deserialization through deserializer.

Defined in

makeSerializerWith

This partial implementation of the serializer will produce a generic record value from a model instance.

It handles multiple features, such as:

  • Serialize instance into generic record value
  • Serialize relation instances into generic record values
  • Serialize generic record values into adapter's data format
  • Only serialize changed instance's values
  • Use model's properties aliases and value transformers.
  • Serialize nested relation instances with circular references support

Usage

import { makeSerializerWith, makeSerializerRecordFactory } from '@foscia/serialization';

const serializer = makeSerializerWith({
createData: (records) => records,
createRecord: makeSerializerRecordFactory(
(instance) => ({ id: instance.id } as Record<string, any>),
(record, { key, value }) => {
record[key] = value;
},
),
});

const data = await serializer.serializeInstance(instance, {
/* ...context */
});

Configuration

NameTypeDescription
createRecordSerializerRecordFactory<Record, Related, Data>Create a serializer record object which can be hydrated and retrieved.
createData(records: Arrayable<Record> | null, context: {}) => Awaitable<Data>Create adapter data value from a set of serialized record. Default to no transformation.
shouldSerialize(serializerContext: SerializerContext<Record, Related, Data>) => Awaitable<boolean>Check if an instance attribute or relation should be serialized or not. Default to value not undefined and changed.
serializeKey(serializerContext: SerializerContext<Record, Related, Data>) => Awaitable<string>Serialize an instance attribute or relation key. Default to key aliasing and normalization.
serializeAttribute(serializerContext: SerializerContext<Record, Related, Data, ModelAttribute>) => Awaitable<unknown>Serialize an instance attribute value. Default to use of attribute transformer.
serializeRelation(serializerContext: SerializerContext<Record, Related, Data, ModelRelation>, related: ModelInstance, parents: SerializerParents) => Awaitable<unknown>Serialize an instance relation's related instance(s). Default to the instance ID.
serializeRelated(serializerContext: SerializerContext<Record, Related, Data, ModelRelation>, related: ModelInstance, parents: SerializerParents) => Awaitable<Arrayable<Related> | null>Serialize an instance relation's related instance(s) (outside of a parent serialization context). Default to the instance ID.
isCircularRelation(serializerContext: SerializerContext<Record, Related, Data, ModelRelation>, parents: SerializerParents) => Awaitable<boolean>Detect if the given context is a circular relation. Default to true if model's relation is in the parents chain.
circularRelationBehavior(serializerContext: SerializerContext<Record, Related, Data, ModelRelation>, parents: SerializerParents) => Awaitable<string>Tell how circular relation should be handled by returning the behavior to use: throw to throw an error, skip to avoid serializing a relation referencing an already serialized instance or keep to avoid serializing already serialized relations. Default to skip.

Defined in