Implement toJSON on models
Description
Various of our database entities are exposed through the API. The JSON representation is often slightly different from the model definition.
JSON serialization of models can be made consistent using the toJSON()
method. This allows to remove custom serialization on a per controller basic and puts the serialization in a consistent place.
I.e. instead of the getAppFromRecord()
function, we could just define toJSON()
on the App
model.
class App extends Model {
toJSON(omittedValues: (keyof types.App)[] = []): types.App {
const { anchors, ...definition } = this.definition;
const result: types.App = {
id: this.id,
$created: this.created.toISOString(),
$updated: this.updated.toISOString(),
domain: this.domain || null,
path: this.path,
private: Boolean(this.private),
locked: Boolean(this.locked),
hasIcon: this.get('hasIcon') ?? Boolean(this.icon),
hasMaskableIcon: this.get('hasMaskableIcon') ?? Boolean(this.maskableIcon),
iconBackground: this.iconBackground || '#ffffff',
iconUrl: resolveIconUrl(this),
longDescription: this.longDescription,
definition,
yaml:
this.AppSnapshots?.[0]?.yaml ??
(!omittedValues.includes('yaml') && yaml.dump(record.definition)),
showAppsembleLogin: this.showAppsembleLogin ?? true,
rating:
this.RatingAverage == null
? undefined
: { count: this.RatingCount, average: this.RatingAverage },
resources: this.template && this.Resources?.length ? true : undefined,
OrganizationId: this.OrganizationId,
OrganizationName: this?.Organization?.name,
screenshotUrls: this.AppScreenshots?.map(
({ id }) => `/api/apps/${this.id}/screenshots/${id}`,
),
messages: this.messages,
};
return omit(result, omittedValues);
}
}
Requirements
-
Implement toJSON()
for models which are exposed through the API. -
Remove custom serialization of models from API controllers.