geminikims
@geminikims
受講生
2,742
受講レビュー
115
講義評価
4.9
유튜브 제미니의 개발실무를 운영하고 있습니다.
16년차 개발자
주요 경력
전 토스페이먼츠 기술 이사 (Director of Engineering)
전 우아한형제들 서버 개발자
전 레진엔터테인먼트 서버 개발자
이외 스타트업 등 7곳의 회사에서 다양한 경험 보유
발표 및 인터뷰
블로그
講義
受講レビュー
- Geminiの開発実務 - コマースバックエンド基本編
- Geminiの開発実務 - コマースバックエンド基本編
- Geminiの開発実務 - コマースバックエンド基本編
- Geminiの開発実務 - コマースバックエンド基本編
投稿
Q&A
CouponService 의존성 의문
안녕하세요 질문 감사드립니다!강의에서 언급했지만 이번 강의에서는 여러 회사를 갔을때 회사마다 구현 스타일이 다를텐데 그와 유사하게 다양한 구현 형태를 볼 수 있게 넣어두었습니다또한 강의 기준으론 팀 내부에 레이어에 대한 규칙이나 합의가 없었기 때문에 정해진 규칙이 없는 상태라고 봐주시면 좋을 것 같습니다 😃결국 여러가지 구현 형태를 보시고 어떤 구현형태가 타당한지 나는 어떻게 할것인지 생각을 많이해보셨으면 좋겠습니다!모쪼록 답이 되었길 바랍니다! 감사합니다!
- 1
- 2
- 23
Q&A
상품 목록 조회 고도화 질문
안녕하세요 질문 감사드립니다![옵션 존재 시 재고 관련]상품 옵션이 존재한다면 구매 단위가 상품옵션이 되는 것 이므로 상품 옵션 단위로 재고를 구성하는게 맞을 것 같습니다!Product 는 상위의 대표 상품에 대한 의미로 사용해야할 것 같고 재고에 대해서는 몰라야할 것 같습니다별개로 조회 시에는 전략이 필요할 것 같습니다.주기적으로 배치를 돌려서 모든 옵션의 재고가 다 떨어진 상품을 목록에서 제외 시키는 방법이 있을 것 같구요준 실시간으로 하려면 매번 전체 옵션의 재고를 체크해야하는 전략이 있을 것 같습니다이런 부분은 요구사항과 서비스 특징을 참고하여 구현하면 될 것 같습니다 [프로모션 관련]제 생각에는 상품 자체의 가격을 변경하는 것은 최종적으로 UI단에서만 그렇게 처리 되면 될 것 같습니다개념적으로 할인이라는 것은 상품 입장에서는 당하는 관점이라고 생각합니다그렇기에 상품에 직접적으로 할인을 설정하는 것 보다는 할인이 별개 개념으로 존재해서 두개가 병합되는 형태가 더 좋다고 생각합니다다만 클라쪽에서 "우리 계산로직 넣기 힘들고 API 하위호환성 문제도있으니 서버에서 최종 금액 주세요" 라고 한다면 Presentation Layer에서 가격을 조합해서 내리면 된다고 생각합니다모쪼록 답이 되었길 바랍니다! 감사합니다!
- 1
- 2
- 30
Q&A
표현 계층에서의 접근 지점이 다양해지는것과 이를 해결하기 위한 파사드의 도입에 대해 제미니님의 생각이 궁금합니다.
안녕하세요! 질문 감사드립니다유사한 질문에 대한 답변이 있어서 링크 전달드립니다!유사 답변2혹시 보시고 추가 질문이 있다면 주시면 감사하겠습니다!
- 1
- 2
- 34
Q&A
제품상세 코드 느끼기
안녕하세요 질문 감사드립니다![질문1]제가 개념도를 활용하는 전략에서는 말씀해주신 방식으로 호출해도 괜찮습니다!격벽을 세워서 개념들의 참조를 통제하고 제어하기 위한 것이니까요! [질문2]이건 전략에 따라 다릅니다만 저는 보통 Controller (Presentation Layer)는 덜 중요하고, 개념을 나타내는 영역이 아니라고 생각합니다.그러므로 Controller 에서 Service 를 조합하는 것도 한가지 방법 중 하나라고 생각합니다! 그래서 Controller 에서 Service 여러개를 조합하는 것 자체가 격벽을 넘는 행위라고 지칭하지 않습니다결국 개념과 격벽을 그리는 이유는 비즈니스,구현 도구 영역을 적절히 지켜내고 계속 성장할 수 있도록 관심을 가지기 위한 수단이기 때문에 그쪽에 집중하는게 맞다고 생각합니다 그 외에는 별개로 Controller에서 Service 조합하는 로직은 이질적이실 수 있습니다 (사실 저도 실무에서 잘 안씁니다ㅎㅎ) 대신 그 상위에 대한 영역을 만들거나 컴포넌트를 만드는 선택을 할 수 있습니다 (Facade, WrapperService, Wrapper 등등) 그것 또한 고민거리니 한번 생각해보시면 좋을 것 같습니다! 관련해선 유사 질문이 있었어서 이 질문의 답변도 참고 부탁드립니다!모쪼록 답이 되었길 바랍니다! 감사합니다!
- 1
- 2
- 45
Q&A
격벽의 순환 참조(?)
안녕하세요 질문 감사드립니다!상황에 따라 다르지만 어플리케이션 이벤트의 사용은 적절한 방법이 될 수 있습니다!회원 탈퇴 이벤트 발행 >> 각 개념에서 이벤트 수신 후 처리이 방식은 만약 탈퇴 후 처리가 여러 개념에 많다면 충분히 의존성을 끊고 관심사를 분리할 수 있는 전략이라고 봅니다 😃다른 전략 하나로는 인터페이스를 활용할 수 있다고 봅니다 UserWithdrawalPostProcessor 같은 인터페이스를 만들어두고, 각 개념에서 UserWithdrawalPostProcessor에 대한 구현체를 다 만들도록 한 후UserService 에선 탈퇴 처리 시 List 를 주입 받아 로직을 순회하여 돌리는 방법도 가능하다고 봅니다이렇게 되면 직접 접근하는 것 보다는 느슨한 의존(직접 아는 것은 아님)을 갖고 있기 때문에 어느정도 괜찮은 전략 중 하나라고 봅니다 😃다만 강의에서 중간에 스치듯 언급했지만, User는 전역적인 개념 수준입니다, 몇몇 개념을 제외하고 모든 것을 알고 연관되어 있죠 😀그렇다보니 사실 회원 탈퇴 구현 도구를 만들고 그 곳에서 대부분 개념에 접근해서 탈퇴처리를해도 문제가 없다고 생각합니다!이미 User를 개념도에 그려보면 그 순간 격벽간 순환 참조는 바로 보이게 됩니다 (이미 순환 참조인거죠ㅎㅎ) 그래서 결국 탈퇴 후 처리 로직의 규모를 보고 구현 전략을 정의하시면 좋을 것 같습니다!모쪼록 답이 되었길 바랍니다! 감사합니다! 😃유튜브에서 다룰만한 주제 같아서 추후에 유튜브에서도 얘기해보겠습니다!이슈 : https://github.com/geminiKim/dev-practice/issues/151
- 1
- 2
- 39
Q&A
결제 관련 서킷 브레이커 전략, 데이터 정합성 및 타임아웃 설정 질문
안녕하세요 질문 감사드립니다![질문1-1]해당 방식의 보정 배치는 규모에 따라다르지만 기본적으로 유효하다고 봅니다!문제 상황을 예로 들면 READY 상태로 배치를 돌리기 때문에 만약 서비스 특정이나, 어떤 이벤트로 고객들이 결제창까지 갔다가 결제를 안하고 서비스를 꺼버리게 되면 데이터가 모두 READY 일텐데 그럼 이 결제건들에 대해서는 무한으로 PG사에 조회를 하는 방식일 것이고데이터가 많기 때문에 배치가 점점 느려질 것 입니다 (조회 기간도 만들긴 하겠지만 미결제건이 폭등할때 기준으로 보면 많을 수 있겠죠)이 부분은 내부 배치도 문제지만 PG사 쪽에서도 건별 요청이 계속 들어올 것이기 때문에 비정상적인 조회로 볼 수 있을 것 같습니다그래서 이걸 대체하려면 다른 전략을 활용 할 수 있을 것 같습니다Payment 의 결제 중 같은 상태를 추가하거나, 별도 테이블에 실패 이력을 쌓거나 (물론 이것도 우리 디비 장애면 안쌓일텐데, 이건 운영 이슈로 해결해야겠죠 ㅎㅎ)또는 이벤트 적재 인프라가 있다면 결제 실패시 이벤트를 발행해서 맥락을 끊어서 볼수도 있을 것 같습니다[질문2-1]적어주신 내용도 타임아웃들을 짧게 잡는 것과 연관이 있습니다!일반적으로 배치나 특이사항을 제외하고는 커넥션 타임아웃은 1초도 넉넉하다고 봅니다정상적인 상황에서 서버와 디비가 같은 네트웍을 사용하게 구성하는게 일반적이고, 그럼 연결을 얻는데는 초 단위일 필요도 없기 때문에 최소한으로 잡아둔 것입니다!다만 소켓타임아웃은 쿼리의 규모, 데이터의 양에 따라도 문제가 생길 수 있는데요, 일반적으로 배치를 제외하고는 그런 쿼리를 만들지 않는게 좋기 때문에 저는 처음부터 길게 주지 않는 편입니다! (추후 정말 필요하면 늘리는 방식)[질문2-2]음.. 이건 사실 매 상황마다 다르기 때문에 어떤 기준은 없는 것 같습니다!대신 쓸대없이 시간을 낭비하지 않게 구성하는게 기본 자세인 것 같습니다시간을 늘려야한다면 충분히 타당한 근거가 있어야한다고 봅니다저도 어디서 들은건데 현대의 대한민국 유저들은 화면이 2.5초만 멈춰있어도 바로 인지를 하고 더 나아가서는 답답함을 느끼기 시작한다고 합니다(대신 결제나 공공기관 사이트 등 몇몇 부분에선 느린 것에 학습이 아주 잘 되어있죠, 기대가 없달까요)반대로 에러가 뜨고 “다시 시도해주세요” 는 적어도 한두번 정도는 짜증을 안 낸다고 하네요(썻던 글이 다 날라가는게 아니라면..)그래서 결국 가능한+현실적인 타협선을 잘 정해서 전체 대기 시간을 조절하는게 좋다고 생각합니다또 우리 서버와 디비 등 내부 통제가능한 인프라에 대해서는 가능한 짧게 잡아주는게 좋다고 생각합니다, 일반적으로 같은 네트워크 망이면 느슨하게 설정할 필요가 없겠죠!각각 답변이 잘 됬나 모르겠네요! 추가 질문은 답글이나 질문으로 올려주시길 바랍니다!모쪼록 답이 됬길 바랍니다! 감사합니다!
- 2
- 2
- 72
Q&A
비회원 개념 추가 시 개선 방향
안녕하세요 질문 감사드립니다!비회원에 대한 방식은 적어주신 것 처럼 여러가지 방식이 있을 것 같습니다그럼 방식은 여러가지고 뭐로 해도 될 것 같은데요! 제가 의견을 드리기전에 wheon06님은 어떤 방식으로 처리하실 것 같으신가요?그리고 왜 그 방식/전략을 써야한다고 생각하실지 궁금합니다!먼저 제 의견을 한가지만 드리면 비회원의 주문,결제 까지 요구사항이 있다면 저는 비회원은 개념이 아니라고 볼 것 같습니다!고민해보시고 의견 답글로 남겨주시면 저도 제 의견을 말씀드리겠습니다!
- 1
- 2
- 49
Q&A
DB 레이어 잘 다루는 법
안녕하세요 질문 감사드립니다!포인트 적립 트랜잭션유사 질문이 있어서 해당 답변 참고 부탁드립니다!https://inf.run/3z6MS 낙관적락 예외 처리예외처리는 상황에 따라 전략을 결정하기 나름이라고 봅니다! Advice 레벨에서 정의할 수도 있고, 한번 더 예외를 감쌀수도 있고, 예외를 아예 먹고 에러 로그를 남기고 지나갈 수도 있죠!상황에 맞춰어서 적절한 구현을 하는게 맞다고 생각합니다! 해당 강의에서는 낙관적락에 대한 부분이 핵심이 아니다보니 Advice 에서 공통 에러로 처리하고, 내부 로그를 통해 추적해서 처리하는 식이라고 이해해주셔도 될 것 같습니다!이것 또한 요구사항과 고객한테 에러를 얼마나 친절하게 알려줄 것인지에 대한 관점으로 생각해보면 좋다고 봅니다! Repository, JpaRepository 분리프로젝트의 구조 자체는 상황을 적절히 잘 봐야합니다! 해당 강의에서 상황 설명을 드렸지만상당히 소규모 팀이고, 요구사항은 매일 변칙적으로 변하고 좀 더 효율적이고 기민하게 작업 할 수 있는 구조를 채택했다고 봐주시면 될 것 같습니다!저는 실무에서도 가능한 작고 심플한 구조를 통해서 서비스를 성장시키는 것을 선호합니다특히 도메인의 진짜 정체에 대해서 잘 모르는 상황에서는 이 구조가 오히려 자유도와 유연함을 통한 이점을 얻기 좋았던 것 같습니다!쩌스트 예제의 경우는 제가 도메인을 온전히 알고있고, 단독 프로젝트기 때문에 강제성을 더 올리기 위해 해당 구조를 썻었습니다! 😃 Repository 가 분리된 경우에서의 검증, 업데이트 로직적어주신 코드 자체도 가능한 스타일 이라고 봅니다! 이런 부분이 사실 팀 내 협의가 하나하나 쌓여있어야하는 부분이겠죠 😃만약 제가 같은 팀이라고 가정하고 해당 코드에 대해 표준을 잡는데 의견을 드린다면비즈니스 레이어로 정의한 곳에 너무 디테일한 로직의 모습이 나와있는 것 같아서 행위 단위로 도구를 만들어 응집도를 올리면 어떨까요?라고 말씀드려 볼 것 같습니다 현재 강의 예제 코드도 리뷰 작성 후 7일 후 업데이트 할수 없는 기준으로 작성 되어있어서 참고해보시면 될 것 같습니다!위의 말씀드렸지만 제 경우는 프로젝트 구조를 1개로 가져가지 않습니다자주 말하지만 소프트웨어는 살아있는 유기체와 같기 때문에 그에 맞춰서 환경을 조성하고 성장 시켜야한다고 생각합니다 😀그런 측면에서 결국 아직 개발의 주도권이 사람에게 있기 때문에 우리가 처한 상황, 비즈니스의 흐름, 일의 속도, 팀의 구성원, 팀의 역량 등등을 고려해서 적절한 프로젝트 구조 를 잡는게 중요하다고 생각합니다!너무 비대하고 구현에 절차가 많고, 도메인을 잘 모르는데 오염이 되기 쉽거나, 오버엔지니어링 하기 쉬운 구조 등등 이런 것들을 언제 쓰는게 좋은지반대로 어떤 상황에서 가볍고 변경이 쉬운 구조를 가야하는지결국 일을 잘 돌아가게하고, 우리 소프트웨어가 효율적으로 커갈 수 있는 구조를 잡는게 더 중요한 것 같습니다!질문이 많아서 제가 모두 다 제대로 답변했는지 모르겠네요! 😅이해가 안가시거나, 추가 질문 있다면 편하게 주시길 바랍니다! 유튜브 시청도 감사합니다!모쪼록 답이 되었길 바랍니다! 완강 후 수강평도 기대하겠습니다!
- 2
- 2
- 57
Q&A
엔티티 연관관계 사용
안녕하세요 질문 감사드립니다!우선 핵심만 말하면 저는 실무에서도 생명주기 가 같지 않으면 연관관계를 걸지 않습니다또한 양방향 관계는 걸지않고, 가급적 OneToMany는 정말 필요한 상황이 아니면 사용하지 않습니다지금 예제로 보면 Order -> OrderItem 은 관계를 맺지 않고 OrderItem -> Order 정도는 걸 수 있다고 보긴합니다!이는 결국 "Order 가 OrderItem 을 필수로 알아야하는가?" 가 핵심입니다 단순히 생성 관점으로만 보지 않고 조회 패턴 (Order 조회 시 OrderItem 을 항상 가져와야하는가? Lazy 로 걸면 되지만, 그럼에도 관계가 있어야하는 이유가 무엇일까? 등의 고민)그래서 저는 가급적 관계 보다는 조합을 선호하고 추후에 필요 시 관계를 지정하는 편입니다(사실 관계를 걸었다가 푸는 것 보다, 안 걸고 키로 조합하다가 거는게 수정이 쉽고, 사이드이펙트가 적은편입니다)이건 일반적으로 제가 사용하는 전략이라 적어주신 것 처럼 팀 컨벤션을 정하는게 좋습니다, 다만 단순히 생성 관점에서만으로 접근하는 것은 좀 더 생각해봐야하는 부분 같습니다 OrderItemRepository는 분명히 다른 구현 때문에라도 어짜피 생길 것 이기 떄문입니다(꾸역꾸역 안 만들겠다면 정산 로직에서 OrderItem 단위 정산을 할때 Order 를 조회해서 분류하거나 OrderRepository에 조금 과한 쿼리가 다 들어가야겠죠)추가적으로 주신 질문은 잘 생각해보면 상품과 재고를 같은 관점으로 볼 것인가를 고민해보면 좋을 것 같습니다정확히 보면 재고는 상품과 직접 연관이 있어야하는가?에 대한 고민을 해볼 수 있을 것 같습니다, 타협할 수 있는 전략으로는 ProductStockXXX 같은 친구를 만들어서 해당 역할을 맡길 수 있을 것 같습니다.추가로 더 고민해보실 거리를 드리면 정확히하면 재고는 주문 보단 "결제/취소"하고 상당히 가깝습니다가령 주문 생성시 재고를 차감한다면 복원은 언제해야할까요?, 그리고 주문 생성하고 사이트를 끄거나 하는 사람의 재고는 어떻게 처리해야할까요?등등 관점으로 한번 더 생각해보시면 좋을 것 같습니다!연관관계 관련 주제에 대한 제 유튜브 영상도 링크드리오니 궁금하시면 한번 보시길 바랍니다!https://www.youtube.com/watch?v=vgNHW_nb2mghttps://www.youtube.com/watch?v=j9bcvidVQgghttps://www.youtube.com/watch?v=VGp1g9irQRI모쪼록 답이 되었길 바랍니다! 감사합니다!완강까지 잘 부탁드리고 수강평도 기대하겠습니다! 추가 질문이 있다면 편하게 주세요!
- 1
- 1
- 44
Q&A
엔티티 상태를 조회하는 시점
안녕하세요! 질문 감사드립니다!적어주신 내용과 유사합니다! 단건 조회시에는 코드 기반으로 조회하는게 가능하다고 생각합니다(추가로 ID기반 조회라면 사실 status를 쿼리에 직접 넣어도 조회 데이터 범위가 명확하기 때문에 성능에도 영향이 없습니다)대부분 목록 조회 시에는 직접 쿼리에 질의하는게 맞다고 생각합니다 (페이징 처리가 있다면 더더욱 그래야겠죠)다만 상태 때문에 불 필요한 인덱스가 추가되어야하는지, 현재 인덱스의 효율이 괜찮은지 등의 구성을 보고 판단하는게 중요하다고 생각합니다!추가로 softDelete의 경우 개인적으로는 직관적이고 예측가능하고 누구나 이해하기 쉬우면서 코드 기반으로 테스트하기 더 쉬운 구조를 선호하다보니, 어노테이션 기반을 그렇게 선호하진 않아서 저는 불호에 가깝습니다! 😅그치만 적절히 검토해서 사용해도 무방하다고 생각합니다!모쪼록 답이 되었길 바랍니다! 감사합니다!완강까지 화이팅 해주시고, 완강 후 후기도 기대하겠습니다!
- 1
- 2
- 51





