#serialization #nestjs
Вопрос:
Я хочу исключить поле пароля из схемы пользователя. Но я никак не могу в этом разобраться.
UserSchema.ts
export type UserDocument = User amp; Document;
@Schema()
export class User extends BaseSchema {
@Prop({ type: String })
firstName: string;
@Prop({ type: String })
lastName: string;
@Prop({ type: String, required: true, unique: true })
email: string;
@Prop({ type: String })
phone: string;
@Prop({ type: String, required: true, unique: true })
userName: string;
@Exclude()
@Prop({ type: String, required: true })
password: string;
@Prop({ type: String })
avatar: string;
}
export const UserSchema = SchemaFactory.createForClass(User);
UserController.ts
@UseInterceptors(ClassSerializerInterceptor)
@Get(':id')
public async getUserById(@Param('id') id: string): Promise<ResponseDto> {
try {
const result = await this.userService.getOne({ _id: id });
return new ResponseDto({
isSuccess: true,
message: 'ok',
data: result
});
} catch (error) {
return new ResponseDto({
isSuccess: false,
message: error,
data: null
});
}
}
Это пользовательский сервис.ts
@Injectable()
export class UserService {
constructor(
@InjectModel('User') private readonly userModel: Model<UserDocument>
) { }
public async getMany(query: object): Promise<User[]> {
const users: User[] = await this.userModel.find(query).exec();
return users;
}
public async getOne(query: object): Promise<User> {
const user = await this.userModel.findOne(query).exec();
return user;
}
public async deleteOne(query: object): Promise<any> {
const result = await this.userModel.deleteOne(query).exec();
if (result.n === 0) {
throw new HttpException('Not deleted', 400);
}
return resu<
}
public async deleteMany(query: object): Promise<any> {
const result = await this.userModel.deleteMany(query).exec();
if (result.n === 0) {
throw new HttpException('Not deleted', 400);
}
return resu<
}
public async updateOne(query: object, user: UserUpdateDto): Promise<User> {
return await this.userModel.findOneAndUpdate(query, user).exec();
}
public async updateMany(query: object, user: UserUpdateDto): Promise<any> {
return await this.userModel.updateMany(query, user).exec();
}
public async add(newUser: UserCreateDto): Promise<User> {
const user = await new this.userModel(newUser);
return await user.save();
}
public async addRange(newUsers: UserCreateDto[]): Promise<any> {
return await this.userModel.collection.insertMany(newUsers);
}
}
Результат чванства таков:
{
"$__": {
"strictMode": true,
"selected": {},
"getters": {},
"_id": {
"_bsontype": "ObjectID",
"id": {
"type": "Buffer",
"data": [
96,
171,
150,
114,
131,
27,
120,
44,
172,
51,
211,
88
]
}
},
"wasPopulated": false,
"activePaths": {
"paths": {
"email": "init",
"userName": "init",
"password": "init",
"_id": "init",
"firstName": "init",
"lastName": "init",
"phone": "init",
"avatar": "init",
"__v": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"_id": true,
"firstName": true,
"lastName": true,
"email": true,
"phone": true,
"userName": true,
"password": true,
"avatar": true,
"__v": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"pathsToScopes": {},
"cachedRequired": {},
"$setCalled": [],
"emitter": {
"_events": {},
"_eventsCount": 0,
"_maxListeners": 0
},
"$options": {
"skipId": true,
"isNew": false,
"willInit": true,
"defaults": true
}
},
"isNew": false,
"$locals": {},
"$op": null,
"_doc": {
"_id": {
"_bsontype": "ObjectID",
"id": {
"type": "Buffer",
"data": [
96,
171,
150,
114,
131,
27,
120,
44,
172,
51,
211,
88
]
}
},
"firstName": "",
"lastName": "",
"email": "ali@gel.com",
"phone": "",
"userName": "ali@gel.com",
"password": "$2b$10$Vp9EYM8fuid.bu2cisp45.QPHdQyPLLlcFeOTPUS98AzUxx3WTekG",
"avatar": "",
"__v": 0
},
"$init": true
}
Есть две проблемы, с которыми я не могу справиться:
1 — Поле пароля все еще находится в ответе. Я хочу исключить это
2 — Объект ответа не является чистым. Есть много областей, которые я не хочу получать.
Ответ, которого я ожидаю, будет:
{
isSuccess: true,
message:'ok',
data: {
"firstName": "",
"lastName": "",
"email": "ali@gel.com",
"phone": "",
"userName": "ali@gel.com",
"avatar": ""
}
}
Комментарии:
1. Преобразование из
ClassSerializerInterceptor
не сработает, если вы обернете DTO внутри другого DTO, как это2. Та же проблема! может быть, класс-трансромер не работает с документами мангуста!
Ответ №1:
Вы можете использовать другой пакет и использовать @ExcludeProperty()
@UseInterceptors(new SanitizeMongooseModelInterceptor())
@Get(':id')
public async getUserById(@Param('id') id: string): Promise<ResponseDto> {
...
}