在 swagger 和控制器中对请求正文使用不同的架构

问题描述 投票:0回答:1

我有以下控制器来创建新用户。请求正文 (

CreateUser
) 有一个可选字段
locationName
。我有一个管道,如果请求正文中未定义,则将
locationName
更改为
null

当我使用

@Body
装饰器时,我可以正确地获取主体,并且
locationName
在运行时永远不会是
undefined

对于 Swagger,我可以看到

locationName
是可选的。但是当我尝试在代码中访问
createUserInput.locationName
时,Typescript 仍然抱怨该值可以是
undefined
(我理解)。

如何为控制器代码引入不同类型和为 Swagger 引入另一种类型?

User
控制器:

@Post("/users")
async createUser(
  @Body(CreateUserLocationPipe) createUserInput: CreateUser
): Promise<User> {
  return await this.usersService.create(createUserInput);
}

CreateUser
班级:

export class CreateUser {
  @ApiProperty({ description: "The email of the user" })
  email: string;

  @ApiProperty({ description: "Location of the user" })
  locationName: string | undefined | null;
}

CreateUserLocationPipe
管道:

@Injectable()
export class CreateUserLocationPipe {
  transform(value: string | null | undefined): string | null {
    if (value.locationName === undefined) {
      value.locationName = null;
    }
  }
}
nestjs swagger nestjs-swagger
1个回答
0
投票

我们可以为控制器的输入创建一个不同的类。

export class CreateUserControllerInput extends OmitType(CreateUser, ["locationName"] as const) {
  locationName: WellKnownLocationName | null;
  locationPlantId: string | null;
}

然后我们可以区分控制器主体和 swagger 的请求主体,如下所示。

@Post("/users")
@ApiBody({ type: CreateUser }) // This is exposed by swagger as the request body
async createUser(
  @Body(CreateUserLocationPipe) createUserInput: CreateUserControllerInput // This is the type for the controller
): Promise<User> {
  return await this.usersService.create(createUserInput);
}
© www.soinside.com 2019 - 2024. All rights reserved.