跳到主要内容

API 校验

Entity.validate() 会在规范化和反规范化过程中被调用。返回 undefined 表示没有错误;如果有错误,则返回字符串形式的错误信息。

字段检查​

校验发生在 Entity.process() 之后、Entity.fromJS() 之前,因此它操作的是 POJO,而不是类的实例。

这里我们可以确保包含 title 字段,并且其类型符合预期。

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,
});

全部字段检查​

validateRequired() 可用于检查所有已定义的字段是否都存在。

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,
});

部分结果​

校验的另一个绝佳用途是混合使用返回不完整对象的 endpoint。当某些字段占用大量带宽,或者对后端来说计算开销很大时,这通常很有用。

可以考虑使用 validateRequired 来减少代码量。

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,
});