본문 바로가기
프로젝트 회고/저쪽 손님께서 보내신 겁니다. 🍸

[칵테일 웹 서비스 프로젝트] 9일 차 회고

by HelloJudy 2022. 4. 29.

📖 2022년 4월 29일


✔️ 오늘 내가 한 일

  • DB 조회 최적화 ( 인덱스 )
  • comment CRUD 완성
  • 유저 정보 수정 코드 리팩토링
  • 백엔드 코드 Fix (리팩토링)

 

 

😥 어려움을 겪은 일

 

1. DB 조회 성능 향상 

 

우리 서비스의 메인 기능이라고 할 수 있는 cocktail dictionary는 모든 칵테일을 조회하기 때문에 네트워크 지연이 있었다. 현재 코드에서는 rank collection 또한 populate 되어있어 더욱 지연되고 있다. 

 

 

 

 

Sol 1 ) populate 제거

 

NoSQL의 장점은 탐색 속도이다.

그런 NoSQL 데이터베이스 구조에서는 최대한 populate를 이용하지 않게, 그리고 양방향 관계가 되지 않게 짜는 것이 좋다고 한다.

 

이런 지연을 해결하기 위한 방법을 계속 생각해보았다.

 

Sol 2) lean() 제거

 

mongoose는 쿼리에 .lean() 붙여 사용하면 된다. lean 쿼리를 이용하면 쿼리 객체가 리턴되는 것이 아니라 순수 JSON object가 반환됩된다. 직접 쿼리를 사용해 리턴된 값을 찍어보면 알 수 있다.

 

Sol 2) Index 추가

 

 

  • MongoDB는 원하는 필드를 인덱스로 지정하여 검색 결과를 빠르게 하는 것이 가능하다고 한다. Doucument가 추가되거나 수정될 때 Index도 새로운 Document를 포함시켜 수정된다고 한다.

 

왼: index 전 / 오: index 후

 

다음과 같이 인덱스 전 후로 차이를 볼 수 있다.

하지만 아직도 만족스러운 단계는 아니라 DB 성능을 최적화하는 방법은 꾸준히 고민하고 찾아봐야겠다.

 

현재 우리 서비스의 데이터는 500개 정도뿐이지만 실제 앞으로 내가 회사에서 다룰 데이터들은 훨씬 크기 때문에 

분명히 이 Trouble은 해결해야 하는 문제이다. 

 

 

Sol 3) Pagination

 

  •  이 부분은 response 값이 달라져서 프론트 의견 중요하다. 
  • 아직 추가로 구현해야 하는 기능이 남아있어 지연 이슈가 우리 프로젝트 상황에서는 우선순위가 아닐 수 있다.

 

 

💡 TIL ( Today I Learned )

 

1) NoSQL

NoSQL에서 populate는 최대한 피하자.

 

 

✔️ 오늘 참고하고 공부한 사이트

 

2) 단단한 코드!

 

1차 프로젝트에서는 user 서비스에서 userId를 params 값으로 받아왔다.

그런데 이건 좋지 못한 코드였다.

 

예시를 들어 설명하면 다른 유저의 정보가 들어있는 Token을 가지고 와서 "나 토큰 있으니깐 문 열어줘!!" 한다면

서버에서는 Token이 유효하니깐 문을 열어준다.

이때 UserId는 params에 담긴 정보를 이용하니 토큰만 있다면 남의 이름으로 게시글을 쓰고 수정하고 삭제를 할 수 있다..!!! 삐용삐용

 

1차 때는 MVP 구현만으로 정신이 없어 간과했던 부분이다. 매우 보안에 취약하다.

 

 

 

< 1차 프로젝트 >

 

< 2차 프로젝트 유저 정보 수정 라우터 >

 

verifyToken 미들웨어 일부분

 

토큰 유효성 검사를 하는 미들웨어에서 토큰이 유효하다면 req.user로 userId를 저장한다.

이때 추출된 req.user로 유저를 확인한다.

 

loginRouter.put("/login/modify", verifyToken, async (req, res, next) => {
  try {
  	// 토큰에서 userId 추출
    const userId = req.user;
    const email = req.body.email ?? null;
    const password = req.body.password ?? null;
    const name = req.body.name ?? null;

    const toUpdate = { email, password, name };
    const updatedUser = await LoginService.modify({ userId, toUpdate });

    if (updatedUser.errorMessage) {
      throw new Error(updatedUser.errorMessage);
    }
    res.status(200).json(updatedUser);
  } catch (error) {
    next(error);
  }
});

 

 

 

💁‍♀️ 오늘 느낀 점

 

리팩토링의 하루!

내가 설계한 API를 명세를 통해 정확하고 자세하게 프론트에 전달하는 것이 중요하다고 느낀 하루이다.

 

오늘은 정말 많은 일을 했다. ㅠㅠ DB 최적화도 공부하고 새로운 MVP도 완성시켰고.. 기능도 리팩토링하고.. 갑자기 잘되던 swagger가^_^ body 값만 안 넣어졌다. (ㅂㄷㅂㄷ)

 

그리고 완성됐다고 생각하고 넘겼던 API가 프론트와 연결하는 과정에서 Issue가 있어 마음이 불편하기도 했다.

🤣 어질어질

 

(분명 refreshToken 이놈이 문제다.)

 

 

그리고..

 

 

하트가 날아오던 오피스아워(?) ㅋㅋㅋㅋ 코치님도 1차 때와 같은 분이라 편하게 질문하고 배울 수 있었다!

 

정말 이런 운이 있을까 할 정도로 엘리스에서 만난 분들은 다 너무 좋고 멋있다!!

우리 JackPot 팀이랑 프로젝트하는 것도 너무 즐겁고 굿굿!!! 

 

내가 시무룩하면 또 파이팅!!!!!이라고 외쳐줄 팀원이 있기 때문에 힘내자!!

 

 

📌 내일 할 일(계획)

 

  • Comment MVP merge
  • 커뮤니티 기능 기획 및 설계 🌟
  • Master Branch Merge (코드 리뷰)
  • Dictionary에서 네트워크 지연 이슈 
  •  
반응형

댓글