Javascript NestJS-从后端返回数据库实体,而不是从DTO返回

Javascript NestJS-从后端返回数据库实体,而不是从DTO返回,javascript,entity,nestjs,dto,Javascript,Entity,Nestjs,Dto,我是NestJs的新手,从后端返回响应实体时遇到了问题 问题是,即使我将Promise PostDTO返回-。它仍然从数据库返回Post实体。使用所有属性和nestjs忽略返回类型 你知道哪里会出问题吗?我认为自动转换在两方面都有效。 也许问题在于回报承诺而不是发帖 我希望有人能帮助我。 谢谢 下面是代码 post.entity.ts import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, } from

我是NestJs的新手,从后端返回响应实体时遇到了问题

问题是,即使我将Promise PostDTO返回-。它仍然从数据库返回Post实体。使用所有属性和nestjs忽略返回类型

你知道哪里会出问题吗?我认为自动转换在两方面都有效。 也许问题在于回报承诺而不是发帖

我希望有人能帮助我。 谢谢

下面是代码

post.entity.ts

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  CreateDateColumn,
} from 'typeorm';

@Entity()
export default class Post {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column()
  perex: string;

  @Column()
  content: string;

  @CreateDateColumn()
  createdAt: Date;
}
邮政dto.ts

import { IsString } from 'class-validator';
import { Exclude, Expose } from 'class-transformer';
@Exclude()
export class PostDTO {
  @Expose()
  @IsString()
  readonly title: string;
  @Expose()
  @IsString()
  readonly perex: string;
  @Expose()
  @IsString()
  readonly content: string;
}
post.repository.ts

import { Repository, EntityRepository } from 'typeorm';
import Post from './post.entity';
@EntityRepository(Post)
export class PostRepository extends Repository<Post> {}

在我的控制器中使用新的iterceptor

import { Controller, Get, Post, Body, UseInterceptors } from '@nestjs/common';
import { ArticleService } from './article.service';
import { ArticleDTO } from './dto/article.dto';
import { TransformInterceptor } from 'src/transform.interceptor';
@Controller('articles')
@UseInterceptors(new TransformInterceptor(ArticleDTO))
export class ArticleController {
  constructor(private readonly articleService: ArticleService) {}
  @Get()
  async getAllPosts(): Promise<ArticleDTO[]> {
    return await this.articleService.getAllPosts();
  }

  @Post()
  async createPost(@Body() post: ArticleDTO): Promise<ArticleDTO> {
    return await this.articleService.createPost(post);
  }
}

从'@nestjs/common'导入{Controller,Get,Post,Body,UseInterceptors};
从“/article.service”导入{ArticleService};
从“./dto/article.dto”导入{ArticleDTO};
从'src/transform.interceptor'导入{TransformInterceptor};
@控制器(“物品”)
@使用拦截器(新转换拦截器(ArticleDTO))
导出类控制器{
构造函数(私有只读articleService:articleService){}
@得到()
异步getAllPosts():承诺{
return等待这个.articleService.getAllPosts();
}
@Post()
异步createPost(@Body()post:ArticleDTO):承诺{
返回等待此.articleService.createPost(post);
}
}

在这些代码更新之后,它按预期工作,因此它返回DTO而不是DB实体。

Typescript是一个非常有用的开发工具,但有时会出现问题。在本例中,您告诉Typescript,
PostController#createPost
将返回一个
PostDTO
,如上所述,它的属性为
title
perex
content
。现在,当您运行对
this.postRepository.save()
的查询时,该方法返回一个
Post
对象,该对象具有
id
title、
perex
content
createdAt
。由于
Post
对象具有与
PostDTO
相同的字段(以及更多字段),因此Typescript不会告诉您返回的对象不相同。类似地,这些类型在运行时消失,因为Typescript是一个开发工具,而不是一个运行时(除非您使用的是Deno),所以JavaScript看到的只是
return等待这个.postRepository.save()

你怎么能避开这件事呢

  • 使用局部变量并删除
    id
    createdAt
    字段
  • 使用诸如
    类转换器
    封送处理
    之类的序列化程序将结果转换为所需对象
  • import {
      Controller,
      Get,
      Post,
      Body,
      UseInterceptors,
      ClassSerializerInterceptor,
    } from '@nestjs/common';
    import { PostService } from './post.service';
    import { PostDTO } from './post.dto';
    @Controller('post')
    @UseInterceptors(ClassSerializerInterceptor)
    export class PostController {
      constructor(private readonly postService: PostService) {}
    
      @Post()
      async createPost(@Body() post: PostDTO): Promise<PostDTO> {
        return await this.postService.createPost(post);
      }
    }
    
    import {
      Injectable,
      NestInterceptor,
      ExecutionContext,
      CallHandler,
    } from '@nestjs/common';
    import { Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    import { plainToClass } from 'class-transformer';
    
    interface ClassType<T> {
      new (): T;
    }
    
    @Injectable()
    export class TransformInterceptor<T> implements NestInterceptor<Partial<T>, T> {
      constructor(private readonly classType: ClassType<T>) {}
    
      intercept(
        context: ExecutionContext,
        call$: CallHandler<Partial<T>>,
      ): Observable<T> {
        return call$.handle().pipe(map(data => plainToClass(this.classType, data)));
      }
    }
    
    
    import { IsString } from 'class-validator';
    import { ApiProperty } from '@nestjs/swagger';
    import { Exclude, Expose } from 'class-transformer';
    @Exclude()
    export class ArticleDTO {
      @Expose()
      @ApiProperty({ required: true })
      @IsString()
      readonly title: string;
      @Expose()
      @ApiProperty({ required: true })
      @IsString()
      readonly perex: string;
      @Expose()
      @ApiProperty({ required: true })
      @IsString()
      readonly content: string;
    }
    
    import { Controller, Get, Post, Body, UseInterceptors } from '@nestjs/common';
    import { ArticleService } from './article.service';
    import { ArticleDTO } from './dto/article.dto';
    import { TransformInterceptor } from 'src/transform.interceptor';
    @Controller('articles')
    @UseInterceptors(new TransformInterceptor(ArticleDTO))
    export class ArticleController {
      constructor(private readonly articleService: ArticleService) {}
      @Get()
      async getAllPosts(): Promise<ArticleDTO[]> {
        return await this.articleService.getAllPosts();
      }
    
      @Post()
      async createPost(@Body() post: ArticleDTO): Promise<ArticleDTO> {
        return await this.articleService.createPost(post);
      }
    }