Как сериализовать ответ nest js с преобразователем классов при получении данных с типом goose? - PullRequest
1 голос
/ 04 марта 2020

Я пытался проработать пример Nest Js для секции сериализации для Mongodb, используя Type goose с использованием библиотеки преобразователя классов. Пример, приведенный в https://docs.nestjs.com/techniques/serialization, показывает только, как использовать сериализацию в TypeORM. Я следовал тому же процессу для Типа goose. Вот что я пробовал до сих пор.

// 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);
  }
  ...
}

Я попытался запустить вызов API для Get () с идентификатором, но вместо исключения 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
}

Кто-нибудь может мне помочь с тем, как правильно сериализовать ответ?

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

это известная проблема ( # 108 ), тип goose (& mon goose) несовместимы с классом-преобразователем / валидатором класса
this потому что тип goose должен преобразовать класс в схему, а mon goose скомпилирует его в модель (которая больше не является классом)

0 голосов
/ 05 апреля 2020

Вот обходной путь:

// 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 
  }
  ...
}

Надеюсь, что это может помочь.

...