MongoDB ID 변환 및 검증 커스텀 데코레이터 작성 방법 (NestJS, class-validator)

소개

MongoDB는 기본적으로 ObjectID를 사용하는데, _id 필드로, 각 문서의 고유 식별자 역할을 합니다. Ref를 사용하거나, populate를 사용할 때, _id를 사용하게 되는데, 이 때, ObjectId를 사용하게 됩니다. 프론트엔드에서 string 타입이나, object 타입으로 받아서 사용할 때, ObjectId로 변환해주는 작업이 필요합니다. 이 때, class-validatortransform을 사용하여, ObjectId로 변환해주는 커스텀 데코레이터를 작성하는 방법을 알아보겠습니다.

설치

1
npm i class-validator class-transformer

프로젝트 구조

1
2
3
4
5
src/
|-- decorators/
|-- TransformToMongoId.ts
|-- index.ts
|-- tsconfig.json

TransformToMongoId.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import {
registerDecorator,
ValidationOptions,
isMongoId,
ValidationArguments,
} from "class-validator";
import { Transform } from "class-transformer";

export default function TransformToMongoId(
validationOptions?: ValidationOptions
) {
return function (object: object, propertyName: string) {
registerDecorator({
name: "transformToMongoId",
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate(value: any) {
const isValidObjectWithId =
typeof value === "object" && isMongoId(value._id) && value._id;
const isValidMongoIdString =
typeof value === "string" && isMongoId(value);
return isValidObjectWithId || isValidMongoIdString;
},
defaultMessage(args: ValidationArguments) {
return `${args.property} must be a valid MongoId`;
},
},
});
Transform(({ value }) => {
const isValidObjectWithId =
typeof value === "object" && isMongoId(value._id) && value._id;
const isValidMongoIdString =
typeof value === "string" && isMongoId(value);
if (isValidObjectWithId) {
return value._id;
} else if (isValidMongoIdString) {
return value;
}
return null;
})(object, propertyName);
};
}
  • 변수 설명: isValidObjectWithId는 객체가 _id 필드를 가지고 있으며, 이 필드가 유효한 MongoDB ID인지 확인합니다. isValidMongoIdString는 값이 문자열로 유효한 MongoDB ID인지 확인합니다.
  • validate 메서드: 이 메서드는 입력된 값이 유효한 MongoDB ID인지 확인합니다.
  • defaultMessage 메서드: 검증 실패 시 표시될 기본 오류 메시지를 반환합니다.
  • Transform: 입력된 값이 객체이고, _id 필드가 유효한 MongoDB ID인 경우, _id 필드를 반환합니다. 입력된 값이 문자열이고, 유효한 MongoDB ID인 경우, 그대로 반환합니다.

사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { IsArray, IsOptional, IsString } from "class-validator";
import { Center } from "@src/centers/centers.schema";
import { User } from "@src/users/users.schema";
import IsValidMongoIdArray from "@src/decorators/isValidMongoIdArray";

export class CreateGymDto {
@IsString()
readonly name: string;

@IsArray()
@IsOptional()
@IsValidMongoIdArray()
readonly managers: (User | string)[];

@IsArray()
@IsOptional()
@IsValidMongoIdArray()
readonly centers: (Center | string)[];
}

CreateGymDto 클래스에서 managerscenters 필드에 IsValidMongoIdArray 데코레이터를 사용하여, MongoDB ID를 검증합니다. @IsValidMongoIdArray()를 사용하면, managerscenters 필드에 있는 값이 MongoDB ID인지 확인하고 객체나 배열로 되어있는 값들을 MongoDB ID로 변환합니다.

결론

TransformToMongoId 데코레이터는 MongoDB ID를 변환하고 검증하는데 유용한 도구입니다. 이 데코레이터는 데이터 일관성을 보장하고, 코드의 가독성을 높여줍니다. 추가적인 개선 사항으로는 복잡한 객체 구조에서도 작동하도록 확장할 수 있습니다.

공유하기