Saltar al contenido principal

Pensar en schemas

Considera una entrada de blog típica. La respuesta de la API para una sola entrada podría verse así:

{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"createdAt": "2013-05-29T00:00:00-04:00",
"commenter": {
"id": "2",
"name": "Nicole"
}
},
{
"id": "544",
"createdAt": "2013-05-30T00:00:00-04:00",
"commenter": {
"id": "1",
"name": "Paul"
}
}
]
}

Definiciones declarativas​

Tenemos dos tipos de entity anidados dentro de nuestro article: users y comments. Usando varios schema, podemos normalizar los tres tipos de entidad:

import { schema, Entity } from '@data-client/endpoint';
import { Temporal } from 'temporal-polyfill';

class User extends Entity {
id = '';
name = '';
}

class Comment extends Entity {
id = '';
createdAt = Temporal.Instant.fromEpochMilliseconds(0);
commenter = User.fromJS();

static schema = {
commenter: User,
createdAt: Temporal.Instant.from,
};
}

class Article extends Entity {
id = '';
title = '';
author = User.fromJS();
comments: Comment[] = [];

static schema = {
author: User,
comments: [Comment],
};
}

Normalizar​

import { normalize } from '@data-client/normalizr';

const args = [{ id: '123' }];
const normalizedData = normalize(Article, originalData, args);

Ahora, normalizedData creará una única fuente de verdad serializable para todas las entidades:

{
result: "123",
entities: {
articles: {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324", "544" ]
}
},
users: {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
comments: {
"324": {
id: "324",
createdAt: "2013-05-29T00:00:00-04:00",
commenter: "2"
},
"544": {
id: "544",
createdAt: "2013-05-30T00:00:00-04:00",
commenter: "1"
}
}
},
// contents excluded for brevity
indexes,
entitiesMeta,
}

Desnormalizar​

import { denormalize } from '@data-client/normalizr';

const denormalizedData = denormalize(
Article,
normalizedData.result,
normalizedData.entities,
args,
);

Ahora, denormalizedData instanciará las clases y garantizará que todas las instancias del mismo miembro (como Paul) sean referencialmente iguales:

Article {
id: '123',
title: 'My awesome blog post',
author: User { id: '1', name: 'Paul' },
comments: [
Comment {
id: '324',
createdAt: Instant [Temporal.Instant] {},
commenter: [User { id: '2', name: 'Nicole' }]
},
Comment {
id: '544',
createdAt: Instant [Temporal.Instant] {},
commenter: [User { id: '1', name: 'Paul' }]
}
]
}

MemoCache​

MemoCache es un singleton que se puede usar para mantener la igualdad referencial entre llamadas, además de mejorar potencialmente el rendimiento en un 2000%. Sus métodos están memoizados.

memo.denormalize​

import { MemoCache } from '@data-client/normalizr';

// you can construct a new memo anytime you want to reset the cache
const memo = new MemoCache();

const { data, paths } = memo.denormalize(
Article,
normalizedData.result,
normalizedData.entities,
args,
);
const { data: data2 } = memo.denormalize(
Article,
normalizedData.result,
normalizedData.entities,
args,
);

// referential equality maintained between calls
assert(data === data2);

memo.denormalize() es igual que denormalize() de arriba, pero incluye paths como parte del valor de retorno. paths es un Array con las rutas de todas las entidades incluidas en el resultado.

memo.query​

memo.query() permite desnormalizar un Queryable a partir de los args únicamente, en lugar de una entrada normalizada.

const data = memo.query(
Article,
args,
normalizedData,
);

Queryable​

Los schemas Queryable permiten acceder al store sin un endpoint. Lo logran mediante el método queryKey, que produce los resultados que normalmente se almacenan en la caché del endpoint.

Esto permite usarlos en estos casos adicionales:

Los Querables incluyen Entity, All, Collection, Query, Union y Scalar. Los campos Lazy producen un Queryable mediante su accessor .query.

interface Queryable {
queryKey(
args: readonly any[],
queryKey: (...args: any) => any,
getEntity: GetEntity,
getIndex: GetIndex,
// `{}` means non-void
): {};
}

Resumen de schemas​

Tipo de datosMutableSchemaDescripciónQueryable
Object✅Entityun solo objeto único✅
✅Union(Entity)objetos polimórficos (A | B)✅
🛑Objectclaves conocidas estáticamente🛑
Invalidate(Entity)eliminar una entidad🛑
List✅Collection(Array)listas ampliables✅
🛑Arraylistas inmutables🛑
Alllista de todas las entidades de un tipo✅
Map✅Collection(Values)mapas ampliables✅
🛑Valuesmapas inmutables🛑
Scalar✅Scalarcampos de entidad que dependen de la lente✅
cualquieraQuery(Queryable)transformaciones personalizadas memoizadas✅
Lazy(Schema)desnormalización diferida✅