항해99 취업 리부트 코스/WIL

[항해 취업 리부트 코스] 개인프로젝트 1주차 후기

봄의 개발자 2024. 4. 23.

알고리즘 주차가 끝나고 개인 프로젝트 주차가 시작되었다. 예약 구매 라는 주제를 선택했다. 1주차라 기능 구현 난이도가 그렇게 높진 않았다. 오랜만 ERD 설계하고 코딩하니까 조금 설렜던 거 같다. 그치만 이게 내가 생각해낸 아이디어가 아니라 큰 틀이 정해진 상태에서 그 안을 채워가야하는 거라 조금 어려운 점도 있었다. 추상적이라서 더 힘들었지 않나 생각한다. 그래서 초반에 어려움이 많았지만 매니저님들이 이를 반영해서 좀 더 구체적으로 틀을 잡아주셨다. 그나마 좀  할만해지지 않았나 싶다!

모두가 같은 주제로 같은 어려움을 고민하고 논의하는 과정에서 많이 배우게 되는 것 같다.

그리고 나도 언젠가 꼭 모각코를,,,


 

1. 이번 주 항해 취업 리부트코스에서 내가 구현한 기능은 무엇인가요?

  • 유저 관리 기능
  • 마이페이지 기능 (회원 정보 변경, 내가 등록한 상품 조회)
  • 상품 관련 기능
  • 위시리스트 기능
  • 상품 주문 기능
  • 배송 기능
  • 반품 기능

 

2. 해당 기능을 구현하기 위해, 어떤 기술적 의사결정을 거쳤나요?

  • 고민한 기술의 종류들에는 무엇이 있나요?
    • 암호화 방식: jacypt, crypto, aes 알고리즘 사용해 직접 구현
  • 위 기술들별로 각각의 장단점이 있다면 무엇인가요?1   Jasypt (Java Simplified Encryption)
    •   장점:
        •   간단한 API로 암호화/복호화 기능을 쉽게 구현할 수 있음
        •   Spring 프레임워크와 연동하여 사용할 수 있음
        •   다양한 암호화 알고리즘(AES, Blowfish 등)을 지원
    •   단점:
        •   암호화 키 관리 등 보안 관련 세부 사항을 직접 구현해야 함
        •   라이브러리 의존성이 생김
    2   Crypto 라이브러리
    •   장점:
        •   다양한 암호화 알고리즘(AES, RSA, ECC 등)을 제공
        •   암호화 키 관리, 난수 생성 등 보안 관련 기능을 제공
    •   단점:
        •   복잡한 API로 인해 초기 학습 곡선이 높음
        •   라이브러리 의존성이 생김
    3   AES 알고리즘 직접 구현
    •   장점:
        •   암호화 과정을 완전히 통제할 수 있음
        •   보안성을 높일 수 있음
    •   단점:
        •   암호화 알고리즘 구현 및 관리에 많은 노력이 필요함
        •   잘못된 구현으로 인한 보안 취약점이 발생할 수 있음
    •  

3. 이번 주 겪은 트러블 슈팅이 있다면 무엇인가요?

1주차에는 환경 세팅 및 Basic 기능 구현이라 트러블 슈팅이 딱히 없었다.

 

 

4. 이번 주 진행된 개인 프로젝트에서 얻은 인사이트는 무엇인가요?

 

(1) 4월 17일 멘토링 

더보기

서비스 별로 마이크로 서비스를 구분할 때, 엔티티 간 연관관계는 어떻게 맺으면 좋을지 궁금합니다.

  • db 먼저 생성하고 나중에 프로젝트마다 필요한 테이블만 조회하는 방식
    • 연관관계 안에서 db끼리 처리되도록, 프로젝트가 세분화 되더라도 필요한 테이블만 가져와서 사용한다.
  • 여러 개의 프로젝트가 하나의 db를 보고 있다. 필요한 값만 가져와서 사용해라
  • 여러 개의 db를 사용하더라도 프로젝트랑 db는 분리되어있다.
  • 게시판 프로젝트에서는 user table을 어쨌든 만들어놔야한다.
  • 필요한 연관관계를 가져와서 사용하도록 해라
    • 결론 : db, 프로젝트 분리해라
    • db 설계할 때는 msa를 고려할 필요가 없다.
    • 코드상 그런거고 db는 하나로 되어있다. 어떤 식으로 가져올지는 개발하면서 고려하면 됨

백엔드 프로젝트 - 프론트를 가장 쉽게 만드는 방법 ?

  • 타임리프, 미리 만들어진 템플릿 사용하기
  • 가장 좋은 건 프론트 섭외
  • restapi 설계 할 때 프론트 입장까지 고려할 수 있다. (한번쯤은 프론트 경험해보는 것도 좋다.)

상품에 대한 재고를 상품 테이블과 상품 재고 테이블로 별도로 구분해야 할지 궁금합니다.

  • 굳이 나눌 필요는 없다. 언제 바꼈는지 로그 파일로 알고 있으면 될 듯
  • 언제 추가됐는지, 언제 제거됐는데
  • 따로 분리해서 테이블 생성해도 필드에 재고 밖에 없어서 조인만 계속 될 것 같음

프로젝트 구현 사항이 추상적이라 erd 설계가 어렵습니다.

  • 명확한 것만 먼저 구현하고 이후에 추가하는 걸로
  • 구글 시트 내용 보지 말고 프로젝트 가이드라인 > 백엔드 1주차 과제 노션 페이지 보고 erd 작성하기

처음부터 MSA를 구성해서 환경을 구성하는 게 좋을지 궁금합니다.

  • msa를 설계를 완벽하게 하고 시작하는 건 어려움
  • 명확하게 역할이 나눠지는 게 보이면 그것부터 나눠라
  • 프로젝트 가이드라인 보고 맞춰서 가면 될 듯

마이크로서비스를 어떤 기준으로 나누면 좋을지 고민입니다.

  • 명확하게 성격이 다르다 - 그 기준으로 하면 됨
  • 해보면 별거아님 …케케
  • 프로젝트를 그냥 나누는 개념일 뿐 지금은 크게 신경쓰지 말고 erd, api 설계부터 하고 나서 어떻게 나눠지겠다가 보이면 그것부터 나눠보기

ETC

  • varchar 사이즈를 필드 특성에 맞춰서 조절해라
  • 좀 더 적합한 타입이 있는지 고민해보기
  • erd 설계 시 연관관계 고려
  • 식별관계가 유리한 경우
    • 외래키 아니고 필드로 키값을 가지고 있는 것
  • flowchart → https://whimsical.com/
  • sql - 웬만하면 대문자/소문자, 들여쓰기 일관성있게
  • 자바 개발자 - 자료형에 민감해야한다.
    • 조금 더 신경쓰기
  • 연관관계 사이클이 문제가 될지? → 시각화 해봐라, 사이클이 아닐 수도 있다.
    • 외래키 매핑을 어떻게 했는지가 중요함
    • 예를 들어 두개의 테이블이 서로의 pk를 갖고 있다? → 문제됨

 

(2) 4월 19일 멘토링

더보기

회원가입 로직

restful → stateless 이메일 인증도 api 호출해야한다. 결론: 회원가입 api, 이메일 전송 api, 이메일 인증 코드 확인 api -> 세가지로 나눠서 진행하면 된다.

이메일 암호화 → 이메일 중복 검증 과정

똑같이 나오는 걸로 적용하면 됨

db에서 모든 사용자를 조회해서 비교하는 건 너무 비효율적!

보안상 이슈는 지금 프로젝트 단계에서 고려하지 않아도 될 듯하다.

다른 방법으로 우회해서 보안성을 보장하도록 하면 됨

패키지 구조

회사마다 다르긴 함

layer 별 or domain 별

msa 환경 공통 코드

공통된 코드를 관리하는 모듈이 있어서 이걸 import 받아서 할 수 있다.

검색 키워드 : 공통 모듈

로그아웃 처리

jwt토큰 만료기간이 있어서 따로 관리 해주지 않아도 되는데

로그아웃하는 시점에서 jwt토큰 사용 못 하게 하고 싶다면

예를 들어 블랙리스트처럼 관리하면 된다.

이미 발급된 토큰을 (만료기간 안 지난 경우) 그 토큰으로 api요청이 오면 “이미 로그아웃된 토큰입니다” 응답

 

(3) 4월 20일 멘토링

더보기

    • jwt token : 서버 입장에서 stateless
    • 상태(데이터)를 jwt가 가지고 있음 (Jwt.io에서 확인 가능)
    • 보안이 중요할 수록 세션을 사용하는 게 맞다.
    • 쿼리를 해야한다면 세션을 사용해야한다.
    • jwt를 stateless 하게 사용하는 게 맞다.
    • 추가 질문 - 요구사항 충족하려면 로그인 기록을 모두 저장해야하는건지?
      • jwt로는 불가능함 (발급하는 순간 로그아웃을 컨트롤 할 수 없음 stateless 이기 때문, 체크를 안 하니까)
      • 토큰을 세션처럼 사용하는 방식으로 해야함
      • 백엔드만으로 구현하기 애매함
        • db 하나만 사용하는 거 아님
        • 엄밀히 다 분리 되는 게 맞음
        • msa의 장점: 한 서비스가 다운 되어도 나머지는 돌아가게 하려고
          • 하나만 사용한다? db 망가지면 모든 서비스 다운됨
        • 분리하는 게 원칙적으로 맞다 → 비용이 비쌈
        • 추가 질문
          • db를 복제하는 등 서버마다 만들 때, 각 도메인 엔티티를 모두 분리해서 각 db에 넣는건지 db마다 모든 엔티티 넣는 게 맞는지
          • 물리적으로 분리가 되는 게 맞고 모든 엔티티를 갖고 있을 수 없다.
          • 동기화가 완전히 되는 건 불가능하다.
          • 각 엔티티만 가고 있는게 맞다.
          • 너무 힘들다? 하나만 써도 연습하는 수준에서는 괜찮음!
          • db 분리했을 때 연관관계를 맺을 수 없다.
            • 물리적으로 분리되
  1. MSA 질문
    1. 각 서비스마다 db를 분리 해야하는지, 연관관계는 어떻게 맺는지
      • db 분리하는 게 맞다. 각 도메인만 저장해놓고
      • 데이터가 물리적으로 분리되어있으니까 연관관계, join 불가능하다.
      • api 통신을 통해서 마치 조인처럼 application에서 조립할 수 있음
      • 속도 측면에서 일반적으로 느림
        • 해결책: grpc (통신 프로토콜)
        • 우리가 사용하는 http는 조금 무겁다. grpc 평균적으로 가벼움(빠르다)
        • http2로 돌아가긴 함
        • grpc 포폴 측면에서 의미있을거임(난이도 있음, 인터페이스에 미리 정해놓는 거라 귀찮음)
          • { "orderNotifcation": ... } → orderNotifcation: 1 라고 가정해두고 1:…
          • 미리 인터페이스에 저장해놓고 압축 같은 걸 해서 데이터 용량이 적으니 빨라짐
          • 인터페이스 미리 지정 → protobuf라는 언어 사용 → 다른 서버에서 미리 알고 있어야하기 때문에 한 서버에서 수정하면 다른 서버에서도 수정해야함 → 귀찮다!
          • 속도를 위해서라면 약간의 희생…
        • ehcache 인메모리로 저장해놓는 거 정도는 괜찮음 (서버 간에 공유가 되지 않는다는 단점
          • 잘 쓰면 좋다
    b. 공통적으로 사용하는 기능은 어떻게 하면 좋을지
    • multi module로 구현한다면 공통 모듈을 정의해서 같이 사용하는 방식
    • 라이브러리화해서 사용 가능 - gradle에 implement해서 사용
    • 멀티 모듈화로 하는 걸 추천하심
      • 공통 코드 관리, repository 따로 파는 거 귀찮음
      • 빌드할 때 에러가 많이 남 → querydsl과 궁합이 좋지 않음
      • 그치만 commit 공유되는 게 싫어서 나눠놓는 걸 선호하심
      • 멀티 모듈 한 번 경험해보는 게 좋긴 함
      • 추가 질문
        • 멀티모듈 msa 에서 어느 서버에서 update되고 그것만 빌드해서 배포??
          • ci/cd에서 잘 해주면 됨
        • 한 모듈에서 update됐는지 어떻게 파악하는지?
          • 브랜치별로 관리 - 하나의 브랜치로 하면 안됨
          • 배포 브랜치를 기반으로 트리거해주면 됨
    c. 리프레시 토큰을 추가해야할지
    • 안해도 된다고 생각하심
    • 실제 서비스가 아니기 때문에 의미가 없다고 생각하심
    • 포폴에서 그렇게 어필이 되는 요소는 아님
  2. etc
    • 멘토님은 join 많은 걸 선호하지 않으심
    • refund안에 refund_detail 넣을 듯 (json 형태로)
      • 변경될 내용이 아니기 때문에 이렇게 해도 괜찮다.
    • 실무가 이론상 논리의 완벽함으로 이뤄지진 않는다…
    • 모든걸 이론상 완벽하게 하지 않아도, 우리의 철학으로 해도 괜찮다… 인터넷에 나온 게 답은 아니다!
    • 결제 시스템 - 각자 원하는대로
    • 개인 프로젝트 패키지 구조
      • controller, service, repository
      • 각 패키지 안에서 도메인 별로 분리
      • 개인 취향임

 

(4) 4월 22일 멘토링

더보기
  • 스케줄러
    • 굳이 특정 시간으로 하지 않아도 주문 후 상태, 특정 날짜가 범위 안에 있다면 상태 변경하도록 처리
    • 하루에 한 번씩만 실행되도록
    • 스케줄러 자체는 계속 돌고 있으면서 상태, 날짜에 대해 상태가 업데이트가 됨
    • 개별 처리 → 조회 쿼리문을 한번에 날리고 filter를 잘 걸어라 (filter >> 1. 상태 2. 날짜)
      • 상태 값에 대해 index 걸어주기
      • 스프링 배치 사용해서 한번에 처리하는 방식도 있음
    • 방법이 스케줄링 밖에 없을까요?
      • 간단하게 기능 구현하려면 스프링 스케줄러 사용
      • 지원해주는 라이브러리가 여러개 있으니 그 중에 골라서 사용
    • 스케쥴러 모듈을 따로 나눠서
      • 에러 발생하면 로그로 보여주거나 후처리 해주는 방식
      • 에러난 거 빼고 나머지만 업데이트 해주는 등
  • 테스트 코드
    • 이슈가 나면 곤란한 기능만 테스트코드를 작성하셨다고 함
    • 자코코: 커버리지 7~80% 정도로 맞춰서 작성
    • 1차로 통합 테스트, 그 다음에는 테스트 필요한 것(레거시 코드, 또는 복잡한 함수)을 단위 테스트 수행
      • mocking 아니면 샘플 데이터 사용
  • 함수화해서 안 헷갈리게 잘 만들어러
  • 주문하기 → 관련 엔티티 생성
    • 환불하기 → 상태 변경
    • 역할, 책임 나눠서 알아서 쏙쏙 뽑아올 수 있도록 구현하라
  • 나만의 패턴
    • dto 클래스 컨벤션
    • 이름 정하는 시간도 줄이고, 인텔리제이 단축키 생성해서 활용
    • 결론: 생산성을 높이세요,,,

 

 

댓글