Validación de la API
Entity.validate() se llama durante la normalización y la desnormalización.
undefined indica que no hay error, y se devuelve un mensaje de error en forma de string si lo hay.
Comprobación de campos
La validación ocurre después de Entity.process() pero antes de Entity.fromJS(), por lo que opera sobre POJOs en lugar de sobre una instancia de la clase.
Aquí podemos asegurarnos de que el campo title esté incluido y sea del tipo esperado.
{"id":"1","title":"first"}
{"id":"2"}
{"id":"3","title":{"complex":"second","object":5}}
import { Entity, RestEndpoint } from '@data-client/rest'; export class Article extends Entity { id = ''; title = ''; static validate(processedEntity) { if (!Object.hasOwn(processedEntity, 'title')) return 'missing title field'; if (typeof processedEntity.title !== 'string') return 'title is wrong type'; } } export const getArticle = new RestEndpoint({ path: '/article/:id', schema: Article, });
Comprobación de todos los campos
validateRequired() se puede usar para comprobar que todos los campos definidos estén presentes.
{"id":"1","title":"first"}
{"id":"2"}
{"id":"3","title":{"complex":"second","object":5}}
import { Entity, RestEndpoint, validateRequired } from '@data-client/rest'; export class Article extends Entity { id = ''; title = ''; static validate(processedEntity) { return validateRequired(processedEntity, this.defaults); } } export const getArticle = new RestEndpoint({ path: '/article/:id', schema: Article, });
Resultados parciales
Otro gran uso de la validación es combinar endpoints que devuelven objetos incompletos. Esto suele ser útil cuando algunos campos consumen mucho ancho de banda o son costosos de calcular para el backend.
Considera usar validateRequired para reducir código.
[{"id":"1","title":"first"},{"id":"2","title":"second"}]
{"id":"1","title":"first","content":"long","createdAt":"2011-10-05T14:48:00.000Z"}
{"id":"2","title":"second","content":"short","createdAt":"2011-10-05T14:48:00.000Z"}
import { Entity, RestEndpoint } from '@data-client/rest'; import { Temporal } from 'temporal-polyfill'; export class ArticlePreview extends Entity { id = ''; title = ''; static key = 'Article'; } export const getArticleList = new RestEndpoint({ path: '/article', schema: [ArticlePreview], }); export class ArticleFull extends ArticlePreview { content = ''; createdAt = Temporal.Instant.fromEpochMilliseconds(0); static schema = { createdAt: Temporal.Instant.from, }; static validate(processedEntity) { if (!Object.hasOwn(processedEntity, 'content')) return 'Missing content'; } } export const getArticle = new RestEndpoint({ path: '/article/:id', schema: ArticleFull, });