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