我创建POST端点来创建一个新实体。 我还创建了用于猫鼬的模式,该模式具有字段userId(用于将该实体连接到指定的用户)和DTO(我在POST方法中使用了该模式)。
@UseGuards(JwtAuthGuard)
@Post("/")
createAction(@Request() req, @Body() createActionDto: CreateActionDto) {
return this.actionService.createAction(req?.user?.userId, createActionDto);
}
DTO:
import { IsString, IsNumber, IsUrl } from 'class-validator';
export class CreateActionDto {
userId: string;
@IsString()
name: string;
@IsNumber()
timeStart: number;
}
模式:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema()
export class Action extends Document {
@Prop()
userId: string;
@Prop()
name: string;
@Prop()
timeStart: number;
}
export const ActionSchema = SchemaFactory.createForClass(Action)
在req属性中,我有userId。创建实体并附加从令牌中提取的userId的最佳方法是什么?
我应该将req传递给服务,并在DTO的服务集userId属性中这样传递吗?:
@Injectable()
export class ActionService {
constructor(
@InjectModel(Action.name) private actionModel: Model<Action>,
) { }
async createAction(req: string, createActionDto: CreateActionDto) {
createActionDto.userId = req.user.userId
// ... save to mongoose createActionDto
}
}
这是正确的解决方案还是还有另一种更好的解决方案?
答案 0 :(得分:2)
我个人将在控制器中设置userId
以便不必传递它:
@UseGuards(JwtAuthGuard)
@Post("/")
createAction(@Request() req, @Body() createActionDto: CreateActionDto) {
createActionDto.userId = req?.user?.userId;
return this.actionService.createAction(createActionDto);
}
如果您有许多不同的控制器和DTO需要userId
,则还可以定义一个拦截器并在其中进行操作以减少重复:
@Injectable()
export class SetUserIdInterceptor implements NestInterceptor {
public intercept(_context: ExecutionContext, $next: CallHandler): Observable<any> {
const request: any = _context.switchToHttp().getRequest(); //instead of any you could also define a super-class for all DTOs that require the `userId`-property
request.body?.userId = req?.user?.userId;
return $next;
}
}
然后您可以按以下方式在路线上使用此拦截器:
@UseGuards(JwtAuthGuard)
@Post("/")
@UseInterceptors(SetUserIdInterceptor)
createAction(@Body() createActionDto: CreateActionDto) {
return this.actionService.createAction(createActionDto)
}