78-Nodejs课程2023:资源:自定义输出处理程序
#typescript #node #mongodb #fastify

我们已经在上一章中定义了输出类型,现在让我们看看如何定义自定义输出处理程序。

目的

有时我们想自定义某些值的最终输出,例如使用uploadsUrl为上传文件生成完整的URL,因为我们仅存储在数据库中uploads目录的相对路径,因此我们需要返回完整的URL上传文件。

自定义输出处理程序

这是我们可以定义自定义输出处理程序的地方,让我们以示例来阐明所有内容,让我们更新我们的用户资源类。

// src/app/users/resources/user-resource.ts
import Resource from 'core/resources/resource';
import { uploadsUrl } from 'core/utils/urls';

export default class UserResource extends Resource {
  /**
   * Output shape
   */
  protected output: any = {
    id: 'number',
    name: 'string',
    email: 'string',
    age: 'number',
    avatar: uploadsUrl,
  };
}

当然,这是不起作用的,因为我们没有将uploadsUrl的呼叫转换为函数调用,所以让我们在基本资源类中进行

// src/core/resources/resource.ts
import { get } from "@mongez/reinforcements";

// this will be used to skip the output property if it is missing from the given resource
const missingKey = Symbol("missing");

export default class Resource {
  /**
   * Constructor
   */
  public constructor(protected resource: any = {}) {
    //
  }

  /**
   * Output shape
   */
  protected output: any = {};

  /**
   * {@inheritDoc}
   */
  public toJSON() {
    // final output
    const data: Record<string, any> = {};

    // loop through the output property
    for (const key in this.output) {
      // get the value type
      const valueType = this.output[key];
      // get the value, and also make sure to skip the output property if it is missing from the given resource
      let value = get(this.resource, key, missingKey);

      // skip the output property if it is missing from the given resource
      if (value === missingKey) {
        continue;
      }

      if (typeof valueType === "string") {
        // cast the value
        value = this.cast(value, valueType);
      } else if (typeof valueType === "function") {
        // call the custom output handler
        value = valueType(value);
      }

      // just for now sett the output value to the data
      data[key] = value;
    }

    return data;
  }

  /**
   * Builtin casts
   */
  protected cast(value: any, type: string) {
    switch (type) {
      case "number":
        return Number(value);
      case "float":
      case "double":
        return parseFloat(value);
      case "int":
      case "integer":
        return parseInt(value);
      case "string":
        return String(value);
      case "boolean":
        return Boolean(value);
      default:
        return value;
    }
  }
}

我们添加了另一个if语句以检查值类型,如果是一个函数,我们将其调用并将值传递给它,然后我们返回结果。

现在,当我们检查响应时,我们会看到这样的东西。

"image": "http://127.0.0.1:3000/uploads/users/my-image.jpg"

正如我们仅在资源对象中所拥有的,users/my-image.jpg,我们要返回完整的URL。

- 结论

在本章中,我们添加了另一个功能,该功能是使用自定义输出处理程序来突变我们想要的最终输出值,这将使我们有很大的灵活性来自定义最终输出。

在下一章中,我们将看到如何使用嵌套资源,另一个资源内的资源!请敬请期待。

â•给我买一杯咖啡。

如果您喜欢我的文章并看到对您有用,则可以buy me a coffee,它将帮助我继续前进并继续创建更多内容。

ð项目存储库

您可以在Github

上找到此项目的最新更新

ð加入我们的社区

加入我们的社区Discord获得帮助和支持(节点JS 2023频道)。

ð视频课程(阿拉伯语)

如果您想以视频格式学习此课程,则可以在Youtube上找到该课程,该课程是阿拉伯语。

ð奖励内容ð

您可能会看这些文章,这肯定会提高您的知识和生产力。

一般主题

软件包和库

React JS软件包

课程(文章)