본문 바로가기
Storify

STORIFY (0125) - ObjectId

by Peter.JH 2024. 1. 26.
728x90

1. user가 생성될때 해당 유저의 friend db 생성하도록 수정.

user schema에   _id: Types.ObjectId; 추가하여 Friend user 부분에 넣어 저장하도록 auth.service에 register 함수 수정

  _id: Types.ObjectId;
@Schema()
export class Friend {
  @Prop({ type: Types.ObjectId, ref: User.name, required: true })
  user: Types.ObjectId;

  @Prop([{ type: Types.ObjectId, ref: User.name }])
  friends: Types.ObjectId[];
}

 

  // 회원가입
  async register(createUserDto: CreateUserDto): Promise<any> {
    // Check if username and email exists
    if (!createUserDto.username) {
      throw new BadRequestException('username is required');
    }

    const userExists = await this.userMongoRepository.findByUsername(
      createUserDto.username,
    );
    if (userExists) {
      throw new BadRequestException('User already exists');
    }

    // Hash password
    const newUser = await this.userMongoRepository.createUser(createUserDto);

    // 저장된 비밀번호 확인
    const savedUser = await this.userMongoRepository.findByUsername(
      newUser.username,
    );
    console.log('Saved hashed password:', savedUser.password);
    const tokens = await this.getTokens(newUser._id, newUser.email);
    await this.updateRefreshToken(newUser._id, tokens.refreshToken);

    // Create friend DB for the new user
    await this.friendsMongoRrpository.createFriend({
      user: newUser._id,
      friends: [],
    });

    // 회원가입 이메일 발송
    await this.mailService.sendWelcomeMail(newUser.email, newUser.username);
    return tokens;
  }

 

수정하다 만난 문제점: 

user schema에 _id를 추가할때 @Prop를 추가하면 오류. 

MongoDB의 ObjectId는 Mongoose 모델에서 자동으로 생성되는 _id 필드를 통해 제공되며, 이는 MongoDB 문서의 기본 키 역할을 한다. 일반적으로 Mongoose 스키마에 _id 필드를 명시적으로 정의할 필요는 없다. Mongoose는 자동으로 이 필드를 생성하고 관리한다.

그러나 TypeScript와 함께 사용할 때, TypeScript의 타입 체크 기능으로 인해 _id 필드에 접근할 때 타입 문제가 발생할 수 있다. 이 경우, 클래스 또는 인터페이스에 _id 필드를 명시적으로 추가하여 타입 오류를 해결할 수 있다.

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types } from 'mongoose';

@Schema()
export class User extends Document {
  @Prop({ required: true, unique: true })
  username: string;

  // 기타 필드 정의

  // _id 필드 명시적 정의
  _id: Types.ObjectId;
}

export const UserSchema = SchemaFactory.createForClass(User);



여기서 Types.ObjectId는 Mongoose의 ObjectId 타입을 나타냅니다. 이렇게 하면 TypeScript 컴파일러가 _id 필드의 타입을 정확하게 인식할 수 있다.

 

 

정리

 

1. 사용자 생성 시 친구 데이터베이스 생성:

- 사용자가 생성될 때 해당 사용자를 위한 친구 데이터베이스도 함께 생성되도록 수정하였습니다. 사용자가 회원가입을 하면, 그 사용자의 `_id`를 이용하여 친구 데이터베이스를 생성하도록 구현하였습니다.

 

2. 사용자 스키마에 `_id` 추가:

- MongoDB에서는 각 문서에 대해 자동으로 `_id`를 생성하며, 이건 Mongoose 모델에서도 마찬가지입니다. 하지만 TypeScript의 타입 체크 기능 때문에 `_id` 필드에 접근할 때 타입 문제가 발생할 수 있습니다. 이를 해결하기 위해 사용자 스키마에 `_id` 필드를 명시적으로 추가하였습니다.

 

3. 회원가입 함수 수정:

- 회원가입을 처리하는 `register` 함수를 수정하여 새로운 사용자가 생성되면 해당 사용자를 위한 친구 데이터베이스도 생성되도록 하였습니다. 또한, 이 함수에서는 사용자의 이메일 주소로 환영 메일을 보내는 기능도 포함되어 있습니다. 

 

 

나는 controller, service에서는 ObjectId를 사용하지않고 string으로 받고 repository안에서만 ObjectId를 사용한다.

 

이런 방식을 사용하는 주된 이유는 controller와 service에서는 데이터의 표현과 비즈니스 로직에 집중할 수 있도록 하기 위함이다. Controller와 service 계층에서는 대부분의 경우 데이터를 문자열 형태로 다루는 것이 더 간편하고 직관적이다. 특히, HTTP 요청을 처리하거나 JSON으로 응답을 전달하는 등의 작업에서는 문자열이 훨씬 더 효율적이다. 반면에, repository 계층에서는 데이터베이스와의 상호작용에 집중하게 된다. 여기서는 MongoDB와 같은 데이터베이스가 요구하는 특정한 데이터 타입, 예를 들어 ObjectId와 같은 것을 사용해야 할 때가 많다. 따라서, 이런 방식을 사용하면 각 계층에서 적절한 데이터 타입을 사용할 수 있게 되어, 코드의 가독성과 유지 관리성을 향상시킬 수 있다.

728x90