5

我一直在尝试使用 Typegoose 使用类转换器库来完成 Mongodb 的序列化部分的 NestJs 示例。https://docs.nestjs.com/techniques/serialization中给出的示例仅显示了如何在 TypeORM 中使用序列化。我对 Typegoose 遵循了相同的过程。这是我到目前为止所尝试的。

// cat.domain.ts

import { prop } from '@typegoose/typegoose';

export class Cat {
  @prop()
  name: string;

  @prop()
  age: number;

  @prop()
  breed: string;
}


// cats.service.ts

@Injectable()
export class CatsService {
  constructor(
    @InjectModel(Cat) private readonly catModel: ReturnModelType<typeof Cat>,
  ) {}

  findAll(): Observable<Cat[]> {
    return from(this.catModel.find().exec());
  }

  findOne(id: string): Observable<Cat> {
    return from(this.catModel.findById(id).exec());
  }
  ...
}

// cat.response.ts

import { ObjectId } from 'mongodb';
import { Exclude, Transform } from 'class-transformer';

export class CatResponse {
  @Transform(value => value.toString(), { toPlainOnly: true })
  _id?: ObjectId;

  name: string;

  age: number;

  @Exclude()
  breed: string;

  constructor(partial: Partial<CatResponse>) {
    Object.assign(this, partial);
  }
}

// cats.controller.ts

@Controller('cats')
@UseInterceptors(ClassSerializerInterceptor)
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  findAll(): Observable<CatResponse[]> {
    return this.catsService.findAll();
  }

  @Get(':id')
  findOne(@Param() params: FindOneParamsDto): Observable<CatResponse> {
    return this.catsService.findOne(params.id);
  }
  ...
}

我尝试使用 id 在 Get() 上运行 API 调用,但breed我没有从响应中排除,而是得到了以下响应。

{
    "$__": {
        "strictMode": true,
        "selected": {},
        "getters": {},
        "_id": {
            "_bsontype": "ObjectID",
            "id": {
                "type": "Buffer",
                "data": [
                    94,
                    93,
                    76,
                    66,
                    116,
                    204,
                    248,
                    112,
                    147,
                    216,
                    167,
                    205
                ]
            }
        },
        "wasPopulated": false,
        "activePaths": {
            "paths": {
                "_id": "init",
                "name": "init",
                "age": "init",
                "breed": "init",
                "__v": "init"
            },
            "states": {
                "ignore": {},
                "default": {},
                "init": {
                    "_id": true,
                    "name": true,
                    "age": true,
                    "breed": true,
                    "__v": true
                },
                "modify": {},
                "require": {}
            },
            "stateNames": [
                "require",
                "modify",
                "init",
                "default",
                "ignore"
            ]
        },
        "pathsToScopes": {},
        "cachedRequired": {},
        "$setCalled": [],
        "emitter": {
            "_events": {},
            "_eventsCount": 0,
            "_maxListeners": 0
        },
        "$options": {
            "skipId": true,
            "isNew": false,
            "willInit": true
        }
    },
    "isNew": false,
    "_doc": {
        "_id": {
            "_bsontype": "ObjectID",
            "id": {
                "type": "Buffer",
                "data": [
                    94,
                    93,
                    76,
                    66,
                    116,
                    204,
                    248,
                    112,
                    147,
                    216,
                    167,
                    205
                ]
            }
        },
        "name": "Sylver",
        "age": 14,
        "breed": "Persian Cat",
        "__v": 0
    },
    "$locals": {},
    "$op": null,
    "$init": true
}

谁能帮我正确地序列化响应?

4

2 回答 2

7

更新:class-transformer 现在可以与 typegoose 一起正常工作,请在此处查找有关如何使用它的文档


这是一个已知问题( #108 ),typegoose (& mongoose) 与 class-transformer/class-validator 不兼容
这是因为 typegoose 需要将类转换为模式,而 mongoose 会将其编译为模型(这不是类不再)

于 2020-03-04T12:55:08.753 回答
2

这是一种解决方法:

// cats.controller.ts
...
import { classToPlain } from "class-transformer";
...

@Controller('cats')
@UseInterceptors(ClassSerializerInterceptor)
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  findAll(): Observable<CatResponse[]> {
    const cats = this.catsService.findAll();
    // transforming the Model to CatResponse class...
    const catResponses = cats.map(cat => classToPlain(new CatResponse(cat.toJSON())))
    return catResponses;
  }

  @Get(':id')
  findOne(@Param() params: FindOneParamsDto): Observable<CatResponse> {
    const cat = this.catsService.findOne(params.id);
    const catResponse = classToPlain(new CatResponse(cat.toJSON()));
    return 
  }
  ...
}

希望它可以帮助。

于 2020-04-05T17:25:42.753 回答