Skip to content

WEEK 4 멘토링 일지

Seung-hyun Kim edited this page Dec 5, 2022 · 1 revision

지난주 BE 좋아요를 질문했는데, 어떻게 해결을 하셨는지?

우리 답변

  • post 를 받으면 AuthService를 받아서 토큰을 decoding해서 id를 반환하는 방식으로 구현함.
  • 토큰을 사용해서 jwt decode → id가 있으면 id를 반환하는 방식이다.
  • id가 있는 경우에만 좋아요들을 찾아서 붙여주는 식으로 구현한다.
  • 미들 웨어를 사용해서 이런 로직을 처리하고 싶었는데, 찾기 힘들어서 서비스를 불러오는 방식이라 찝찝하다.

멘토님 답변

  • 괜찮을 것 같다.
  • 미들웨어적으로 나눠도 controller 안에서 쪼개져야 해서. 어떻게 보면 로직 자체가 한 곳에 몰려 있다고 볼 수 있다.
  • 만약에 로그인 했는지 여부에 따라서 수행해야 할 게 좋아요 말고 더 늘어난다면 그때 고민해야 할 것 같다.

로그인 한 사용자와 로그인하지 않은 사용자의 메소드를 분리하는것은?

멘토님 답변

  • 지금 자체는 좋아요만 있는데, 그 영역이 많이 늘어난다면 당연히 분리하는 것이 좋을 것 같다.

우리 답변

  • 지금은 비슷한 로직들이 많이 겹치는데 메소드를 분리해도 되나? 생각이 든다.

swagger 써보니까 decorator가 너무 많다. 현업에서는 어떻게 사용하는지?

멘토님 답변

  • 일단 사용하는데 마찬가지로 지저분하게 사용한다.
  • 이렇게 지저분하게 swagger를 쓰는거만으로도 대단하다.
  • API문서가 없거나, 방치하는 경우도 있다.
    • 만약 swagger 없으면 따로 개발해야 한다.
  • 그런데 가끔 외부 사람들과 협업해야 할 경우 → API 스펙을 전달하면 끝인데, 그럴 수 없어서 따로 문서를 작성하는 경우가 있는데, swagger가 정말 좋다.
    • 한번 더 일 하는 부분을 막아주고,
    • 적어도 코딩하는 시기에 같이 수정이 되므로 쉽다.

원래 목표가 캐시같은걸 사용해서 최적화하는 경험인데..

우리 질문

  • 어느정도 목표했던 기능들을 얼추 다 만들었는데, 너무 기본적인 CRUD가 아닌가? 하는 생각이 든다.
  • 기술적인 도전이 많은 것 같은데, FE는 작업량이 많아서
  • 어떤 기능들을 할 수 있을까? → 알림, 추천순으로 보여주기와 같은 부분을 생각해왔다.
  • 기능이 부족할 때 새롭게 기능을 넣어서 만드는 것이 좋을까?

멘토님 답변

  • 물론 여유가 된다면 추가적으로 넣는것도 괜찮을 것 같다.
  • 추천순 = 정렬 옵션으로 이해해도 될지?
    • 추천순으로 들어간다 = 여러가지 조건들로 하는 게 아니라, [인기 게시물] 을 순서대로 볼 수 있는 그런 기능을 만들고 싶었다.
  • 포스트 리스트를 가져올 때 인기 게시물은 어떻게 판단하는지?
    • 어떻게 보면 정렬 기준을 바꾸는 것인데 (시간순 → 특정조건순) 게시물 리스트를 가져오는 쿼리쪽에 조건만 변경하는 방식이다.
      • 무한 스크롤 방식에서 지금은 시간순서대로 사용하기 때문에 위에 이전거, 아래 최신거 이런식으로 들어와 있는데,
      • 이를 다른 조건으로 바꾸면 → redis를 적용해 볼 예정이다.
        • sync를 계속 맞출것인지? → NO. 인기 게시물이라는게 그렇게 많이 잡아먹는게 아니라고 생각해서 특정 시간, 기간마다 갱신하는 것으로 생각 중이다.
        • 오늘의 인기 게시물, 금주의 인기 게시물과 같은 부분을 하면 좋다고 생각한다.

클라이언트 → S3 과정에서 URL이 노출된다.

멘토님 답변

  • 클라에서 S3로 갈 때 따로 인증 과정이 없기 때문에 위험할수도 있다.
  • 보통은 서버에서 거의 보낸다.
  • 보안을 떠나서 이미지 전처리를 위해 서버로 보내는 경우 있다.
  • 혹은 환경에 따라 이미지 최적화가 달라질수도 있다. (데스크탑용, 모바일용, 초고해상도, 썸네일 추출 등)
    • 유저한테는 섬네일용,모바일용 → 이런거 받을 필요 없이 서버에서 가공하고 생성해도 좋을듯 하다.

데이터 베이스를 접근하는 레이어에서 데이터베이스에 삽입하는 연산 등을 대비해서 에러 핸들링 할 필요가 없는가?

멘토님 답변

  • NO. 핸들링을 해야 한다.
  • 에러를 뱉는 곳이 데이터베이스 접근하는 곳에서 뱉어야 하느냐? 를 질문하는 것이면
    • insert 연산이나 find를 하면 쿼리가 날라가는데, 그런 쿼리가 실패했을 경우를 대비해서 try-catch 등 명시적 에러를 던질 필요는 없는건지?
    • 를 고민하고 던져줘야 하고, 그 에러를 처리하는 곳을 어디서 할 지 고민해야 한다.
  • 함수의 호출-호출-호출 이렇게 연결되는데 (컨트롤러-서비스-… 이렇게 지나감) 이걸 어디서 처리할 것이냐, 이걸 클라이언트까지 노출할 것이냐, 이 에러는 서비스단에서 처리하고 서비스에 지장 없이 하도록 할지 고민해야 한다.
    • 어떤종류, 어떤 도메인인지에 따라 선택하고,
    • 보통은 여러 레이어에서 재활용되는 repository, service → 에러 직접 처리하지 않고 에러를 그냥 throw 하는 것을 선호한다.
    • 비즈니스와 의존성이 깊숙히 있는 지점에서는 에러를 해결하지 않는다. 보통 에러를 내고 던진다.
    • ex) Insert를 해야 하는데 값의 validation이 틀린 경우 → 기본 값으로 공백을 insert 한다. (에러 없이) = 이런 식으로 절대 하면 안된다.. 이게 에러가 나서 공백이 들어간건지, 진짜 공백이 들어간건지 모르기 때문이다.
      • 암묵적으로 에러가 아닌 것으로 감싸는 부분 주의하자.
    • 사용하는 레이어에서는 에러를 찾을 수 없기 때문에 무조건 던져줘야 한다.
      • 서비스가 멈추고, 유저가 보더라도 던지는게 좋다.
      • 그러나 도메인 상 에러가 아니라 validate 차원에서 값을 변경해서 저장은 물론 좋다.
  • 큰 회사로 가게 되면 전체적인 개발이 아니라 특정 function, module, repository 등만 개발하고 ,다른 개발자가 가져다가 쓸 수도 있다.
    • 이걸 내부적으로 처리를 해 버리면 가져가서 쓰는 곳에서는 에러가 나는 지도 모른다.
    • 에러가 나면 funciton 외부로 뱉어주는 버릇을 들여야 한다.
    • 처음에 말한 것과 연결해서 어디까지 에러를 뱉는가? → 중간에 에러를 처리하는 지점에 대한 고민해야 한다. (보통은 도메인을 시작하는 부분에서 많이 처리, 깊숙한 곳에서는 무조건 뱉어준다.)

Repository에서 에러를 던질 때 typeorm 에러가 나오면 커스텀 에러로 던지나?

멘토님 답변

  • 케이스 바이 케이스지만,
  • 규모가 작은 팀에서는 그냥 사용한다.
  • 만약 규모가 되게 크고, 스택이 다양하고, db가 여러개 → 에러를 그대로 뱉어버리면 다른 스택을 쓰는 곳에서 받으면 이해하기가 쉽지 않다.
  • 사실 이정도 규모 되면 에러 처리를 위한 컨벤션이 있을듯 하다.

서버 로그는 어떤 작업에 대해서 띄우고, 라이브러리 사용하는지

멘토님 답변

  • 로그의 목적 = 왜 필요한지? = 에러같은게 났을 때 보기 편하면 좋을듯 싶기 때문이다.
  • 그러면 당연히 로그를 찍어야 하는 곳 = 에러가 나는 곳 = catch문 안
  • 로그
    • feature가 잘 수행 될 때 input을 로깅하는 경우 혹은
    • 에러 처리용
  • throw가 계속 되는 부분에선 남기지 말고 에러 처리 지점에서 남겨도 좋을듯 하다.
  • 로그는 BE에서 아마 로그파일 쓰는 부분이 지원된다.
  • 보통 로그를 쓰는 부분 → 시스템에 파일로 남기는데,
    • 그런데 용량을 많이 먹는다. (하드웨어 용량 부족 조심)
    • 보통 1달에 한번씩 압축해서 다른곳에 업로드한다.
  • 로그파일을 쌓아놔봤자 열어봐도 사람이 보기 힘들다.
    • 로그를 입력받아서 visual하게 보여주는 툴 → 로그 시스템
    • 보통 이런 툴을 사용해서 봄 (가장 많이 쓰는거 : ulk꺼? 사용하신다고 함.)
    • 하지만 이런 툴을 프로젝트에 적용하는건 아닌 것 같다고 하다.

이력서에 어떤거를 어필할 지

  • 내가 어떤 기여를 해서 이 서비스의 어떤 지표가 좋아졌다. 라는 부분이 있으면 좋은데 사실 경력이 있어야 성능 개선하는게 의미가 있다.
  • 지금 레벨의 프로젝트에서 유저들이 사용하는 사용성이 충분하지 않기 때문에 지표가 그렇게 중요하지는 모르겠다.
  • 빌드타임을 줄였다. 와 같은 부분은 필요한데,
  • 퍼포먼스가 어느정도 좋아졌다. 는 포트폴리오로 어필하기 힘들 수 있다.
    • 넣어도 유저가 얼마나 된다고 퍼포먼스가 개선되는 걸 어필을 하는가? 라고 생각 할 것 같다.
  • 지표나 성능적인 부분보다는, 어떤 기술적인 고민을 하고 있고 시도를 하고 있다. 를 주로 사용하고,
  • 기술적 시도로 마무리가 아니라 생각이 확장되고, 다른 부분에도 시도를 하면 좋았을 듯 하다.
    • 단순 과제가 아니라 어떻게 발전하고 있는지 보여주는 부분이 차별화되어 보였다.
  • 이력서에 어필하는 것에 포커스를 줄 수도 있지만, 진심으로 사용자가 어떻게 도움이 될 지, 더 성공적인 서비스가 될 지를 고민하고 이력서에 담는걸로도 충분하다고 생각됨.

리뷰어님의 간단한 기술 소개 - 재귀함수

| 자기 자신을 호출하는 함수

  • 의도적으로 사용을 할 수도 있는데, 의도적으로 사용하지 않아도 이거는 재귀로 풀면 되겠는데? 라는 느낌이 들어서 쓰는 경우가 많다.
  • 그러나 항상 재귀가 정답은 아님.
    • 함수의 Input-Output이 계속 변함
    • 사람이 계속 쫒아가기도 힘듬
    • 그래서 depth가 깊어지는거 생각 없이 로직을 정확히 짜고 테스트 하는 방식으로 많이 사용
  • 재귀 함수의 문제점
    • 가장 큰 문제 - 스택 오버플로우 : 함수를 계속 호출하니까 자기가 호출된 곳을 계속 기억해야 함. 그리고 호출될 때에 스택에 파라미터 등을 포함해야 함.
    • 만약 무한루프가 돌면 당연히 스택오버플로우
    • 분기가 있더라도 반복이 너무 오래 반복하면 스택오버플로우
    • 스택오버플로우 = 유저의 컴퓨팅 환경에 따라 엔진이 매번 다르게 판단함. (물론 비슷한 환경이면 거의 비슷함)
    • 원칙적으로는 컴퓨팅 환경에 따라 스택오버플로우 지점이 매번 달라짐 = 코딩할 수 없다.
      • “몇번 반복” 하고 그 이상은 no 라는 로직 자체가 위험함
  • 꼬리재귀 << 재귀의 단점을 줄일 수 있는 부분
  • 일반적인 재귀는
    • fn → return fn * n 이런식으로 있으면 다음 fn에서 저 지점을 기억하고 있어야함
    • 그 다음 fn에서도 return 위치를 기억하고…
    • 이런 과정이 필요함
    • 마지막에 리턴이 되면 바로 직전 function context로 복귀 반복
    • 리턴될 위치를 알아야 할 이유 : 그 위치에 돌아가서 마무리 할 연산 (* N) 이 남아있기 때문에 돌아가야 할 위치를 기억해야 함.
  • 꼬리 재귀 → 리턴해야 할 값을 fn에 포함 → 중간에 돌아가야 할 위치가 쌓이지 않음
  • node는 꼬리재귀를 지원하고, front쪽은 safari에서만 되는걸로 알 고 있음. (적어도 몇달 전까지…)
  • 보통 코딩 테스트 → 브라우저 엔진에서 X (서버에서 돌아감) → node를 고르면 node engine으로 돌아가니까 코테에서 사용해보면 좋을 듯
    • 재귀로 짜는데 꼬리재귀 안 쓸 거면 일반 for문이 더 유리할 것 같다.

WeView 👨‍👨‍👦‍👦

💾 개발 기록

2주차 Tech Post
3주차 Tech Post
4주차 Tech Post
5주차 Tech Post
6주차 Tech Post

⛹🏻 주간 스프린트

1주차 스프린트
2주차 스프린트
3주차 스프린트
4주차 스프린트
5주차 스프린트
6주차 스프린트

📑 주간 회고

📝 1주차 주간 회고
📝 2주차 주간 회고
📝 3주차 주간 회고
📝 4주차 주간 회고
📝 5주차 주간 회고
📝 6주차 주간 회고
Clone this wiki locally