Partial Entities
Sometimes you have a list endpoint whose entities only include a subset of fields needed to summarize.
ArticleSummary
{
"id": "1",
"title": "first"
}
Article
{
"id": "1",
"title": "first",
"content": "Imagine there was much more here.",
"createdAt": "2011-10-05T14:48:00.000Z"
}
In this case we can use Entity.validate() to ensure we have the full and complete response when needed (detail views), while keeping our state DRY and normalized to ensure data integrity.
api/Article
ArticleDetail
import { validateRequired } from '@data-client/rest'; import { Entity, createResource, schema } from '@data-client/rest'; export class ArticleSummary extends Entity { id = ''; title = ''; pk() { return this.id; } // this ensures `Article` maps to the same entity static key = 'Article'; static schema = { createdAt: Temporal.Instant.from, }; } export class Article extends ArticleSummary { content = ''; createdAt = Temporal.Instant.fromEpochSeconds(0); static validate(processedEntity) { return validateRequired(processedEntity, this.defaults); } } export const ArticleResource = createResource({ path: '/article/:id', schema: Article, }).extend({ getList: { schema: new schema.Collection([ArticleSummary]), }, });
Detail data in nested entity
It's often better to move expensive data into another entity to simplify conditional logic.
api/Article.ts
class ArticleSummary extends Entity {
id = '';
title = '';
content = '';
createdAt = Temporal.Instant.fromEpochSeconds(0);
static schema = {
createdAt: Temporal.Instant.from,
meta: ArticleMeta,
};
pk() {
return this.id;
}
// this ensures `Article` maps to the same entity
static key = 'Article';
}
class Article extends ArticleSummary {
meta = ArticleMeta.fromJS();
static validate(processedEntity) {
return validateRequired(processedEntity, this.defaults);
}
}
class ArticleMeta extends Entity {
viewCount = 0;
likeCount = 0;
relatedArticles: ArticleSummary[] = [];
static schema = {
relatedArticles: [ArticleSummary],
};
}
const ArticleResource = createResource({
path: '/article/:id',
schema: Article,
}).extend({
getList: { schema: new schema.Collection([ArticleSummary]) },
});