问题描述
我的照片和标签对象有 DTO,如下所示:
I have DTOs for my Photo and Tag objects that look like this:
export class PhotoDto {
readonly title: string
readonly file: string
readonly tags: TagDto[]
}
export class TagDto {
readonly name: string
}
我在我的 photo.service.ts
中使用 PhotoDto
并最终在 photo.controller.ts
中用于创建照片:
I use the PhotoDto
in my photo.service.ts
and eventually in the photo.controller.ts
for the creation of Photo:
// In photo.service.ts
async create(createPhotoDto: PhotoDto): Promise<PhotoEntity> {
// ...
return await this.photoRepo.create(createPhotoDto)
}
// In photo.controller.ts
@Post()
async create(@Body() createPhotoDto: PhotoDto): Promise<PhotoEntity> {
// ...
}
但是,API 主体中的输入应具有以下结构:
However, the input in the Body of the API is expected to have this structure:
{
"title": "Photo Title",
"file": "/some/path/file.jpg",
"tags": [
{
"name": "holiday"
},
{
"name": "memories"
}
]
}
如何更改 Body
的输入形状以接受此结构?
How can I change the input shape of the Body
to accept this structure instead?
{
"title": "Photo Title",
"file": "/some/path/file.jpg",
"tags": ["holiday", "memories"]
}
我尝试创建 2 个不同的 DTO,一个 CreatePhotoDto
和一个 InputPhotoDto
,一个用于控制器中所需的输入形状,另一个用于服务和实体,但这最终会非常混乱,因为在 2 个 DTO 之间进行转换需要做很多工作.
I have tried creating 2 different DTOs, a CreatePhotoDto
and an InputPhotoDto
, one for the desired input shape in the controller and one for use with the service and entity, but this ends up very messy because there is a lot of work with converting between the 2 DTOs.
使用与 Post
请求的 Body
不同的输入形状,然后将其转换为实体所需的 DTO 的正确方法是什么?
What is the correct way to have a different input shape from the Body
of a Post
request and then have it turned into the DTO required for use by the entity?
推荐答案
您可以使用 ValidationPipe()
的自动转换:
You can use the auto-transform of the ValidationPipe()
:
1) 将 ValidationPipe
添加到您的控制器:
1) Add the ValidationPipe
to your controller:
@UsePipes(new ValidationPipe({ transform: true }))
@Post()
async create(@Body() createPhotoDto: PhotoDto): Promise<PhotoEntity> {
// ...
}
2) 将 @Transform
添加到您的 PhotoDto
:
2) Add a @Transform
to your PhotoDto
:
// Transforms string[] to TagDto[]
const transformTags = tags => {
if (Array.isArray(tags)) {
return tags.map(tag => ({name: tag}))
} else {
return tags;
}
}
import { Transform } from 'class-transformer';
export class PhotoDto {
readonly title: string
readonly file: string
@Transform(transformTags, {toClassOnly: true})
readonly tags: TagDto[]
}
这篇关于NestJs:如何让 Body 输入形状与实体的 DTO 不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!