【发布时间】:2020-12-28 22:37:21
【问题描述】:
我是 NestJs 的新手,我遇到了从后端返回响应实体的问题。
问题是即使我返回 Promise-PostDTO-.它仍然从数据库返回 Post 实体。用所有的属性和nestjs忽略返回类型。
你知道哪里有问题吗?我认为自动转换在两种方式下都有效。 也许问题在于返回 Promise 而不是 PostDTO。
我希望有人可以帮助我。 谢谢
下面的代码。
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;
}
post.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> {}
post.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import Post from './post.entity';
import { PostRepository } from './post.repository';
import { PostDTO, PostRO } from './post.dto';
@Injectable()
export class PostService {
constructor(
@InjectRepository(Post) private readonly postRepository: PostRepository,
) {}
async createPost(post: PostDTO): Promise<PostDTO> {
return await this.postRepository.save(post);
}
}
post.controller.ts
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);
}
}
根据 Jay McDoniel 的回答,我将代码重构为此。
我使用了转换类的自定义 nestjs 拦截器。
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)));
}
}
我还使用类转换器包重构了我的 DTO。
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);
}
}
这些代码更新后,它按预期工作,因此它返回 DTO 而不是 DB 实体。
【问题讨论】:
标签: javascript entity nestjs dto