【问题标题】:How to setup a separate DTO other than Persistable Model in Loopback 4如何在 Loopback 4 中设置除 Persistable Model 之外的单独 DTO
【发布时间】:2018-11-28 07:51:01
【问题描述】:

考虑一下这个 lb4 模型

@model({
  name: 'users'
})
export class User extends Entity {
  @property({
    type: 'number',
    id: true,
  })
  id: number;

  @property({
    type: 'string',
    required: true,
  })
  first_name: string;

  @property({
    type: 'string',
  })
  middle_name?: string;

  @property({
    type: 'string',
  })
  last_name?: string;

  @property({
    type: 'string',
    required: true,
  })
  username: string;

  @property({
    type: 'string',
  })
  email?: string;

  @property({
    type: 'string',
  })
  phone?: string;

  @property({
    type: 'string',
    required: true,
  })
  password: string;

  @property({
    type: 'string',
  })
  external_id: string;

  @belongsTo(() => UserTenant)
  created_by: number;

  @belongsTo(() => UserTenant)
  modified_by: number;

  constructor(data?: Partial<User>) {
    super(data);
  }
}

目前,如果我们使用 lb4 cli 为该模型创建存储库和控制器,它将生成与输入/输出相同模型的路由方法 CRUD。但是,我们想要的是有一个单独的 DTO 模型(非持久化到 DB)用作控制器的输入/输出 DTO,不包括属性密码、created_by 和 modified_by。一种方法是手动创建这样一个模型类并写下一个转换器类,它将 UserDTO 对象转换为上面的用户模型(复制各个属性)。但这似乎是一个开销。此外,我们希望对更多模型执行此操作。所以,以这种方式做这件事似乎不是正确的方法。 lb4 是否提供了更好的方法来实现这一点?

【问题讨论】:

    标签: node.js loopbackjs dto


    【解决方案1】:

    目前看来,现在有办法在 LB4 中本地“隐藏”属性。然后我最终用一个新的实体 HideableEntity(扩展实体)修改了 Entity 类。在 HideableEntity 中,我像这样修改了 toJson() 函数:

    import {Entity, AnyObject} from '@loopback/repository';
    import {Options} from '@loopback/repository/src/common-types';
    
    export abstract class HideableEntity extends Entity {
      /**
       * Serialize into a plain JSON object
       */
      toJSON(): Object {
        const def = (<typeof HideableEntity>this.constructor).definition;
        if (def == null || def.settings.strict === false) {
          return this.toObject({ignoreUnknownProperties: false});
        }
    
        const json: AnyObject = {};
        for (const p in def.properties) {
          if (p in this) {
            json[p] = asJSON((this as AnyObject)[p]);
          }
        }
        return json;
      }
    
      /**
       * Convert to a plain object as DTO
       */
      toObject(options?: Options): Object {
        const def = (<typeof HideableEntity>this.constructor).definition;
    
        let obj: AnyObject;
        if (options && options.ignoreUnknownProperties === false) {
          obj = {};
          for (const p in this) {
            if (def != null && def.properties[p] && def.properties[p]['hide']) {
              continue;
            }
            let val = (this as AnyObject)[p];
            obj[p] = asObject(val, options);
          }
        } else {
          obj = this.toJSON();
        }
        return obj;
      }
    }
    
    function asJSON(value: any): any {
      if (value == null) return value;
      if (typeof value.toJSON === 'function') {
        return value.toJSON();
      }
      // Handle arrays
      if (Array.isArray(value)) {
        return value.map(item => asJSON(item));
      }
      return value;
    }
    
    function asObject(value: any, options?: Options): any {
      if (value == null) return value;
      if (typeof value.toObject === 'function') {
        return value.toObject(options);
      }
      if (typeof value.toJSON === 'function') {
        return value.toJSON();
      }
      if (Array.isArray(value)) {
        return value.map(item => asObject(item, options));
      }
      return value;
    }
    

    然后现在在我的模型扩展 HideableEntity 中,我添加属性 hide: true,它不会被添加到 JSON 输出中:

    export class User extends HideableEntity {
      @property({
        type: 'number',
        id: true,
        required: false,
      })
      id: number;
    
        @property({
            type: 'string',
            required: true,
        })
        email: string;
    
        @property({
            type: 'string',
            required: true,
            hide: true,
        })
        password: string;
    
        [...]
    

    在上述情况下,密码将被隐藏。

    【讨论】:

      猜你喜欢
      • 2020-09-28
      • 2020-12-18
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 2020-01-30
      相关资源
      最近更新 更多