- 유튜브 제미니의 개발실무를 운영하고 있습니다. 
- 16년차 개발자 
주요 경력
- 전 토스페이먼츠 기술 이사 (Director of Engineering) 
- 전 우아한형제들 서버 개발자 
- 전 레진엔터테인먼트 서버 개발자 
- 이외 스타트업 등 7곳의 회사에서 다양한 경험 보유 
발표 및 인터뷰
블로그
강의
수강평
- 제미니의 개발실무 - 커머스 백엔드 기본편
- 제미니의 개발실무 - 지속 성장 가능한 소프트웨어를 만들어가는 방법
- 제미니의 개발실무 - 지속 성장 가능한 소프트웨어를 만들어가는 방법
- 제미니의 개발실무 - 커머스 백엔드 기본편
- 제미니의 개발실무 - 지속 성장 가능한 소프트웨어를 만들어가는 방법
게시글
- 질문&답변 - 상품 상세 컨트롤러 내 서비스 호출 질문 - 안녕하세요 질문 감사합니다! 질문이 좀 산개 되어있어서 😅 하나씩 정리해서 답변드리겠습니다![질문1]적어주신 내용들 보다는 개념간의 적절한 격벽 구성을 유지하며 가장 쉽게 요구사항을 구현하는 목적을 달성하기 위한 전략 중 하나를 적용하였다고 봐주시면 됩니다+ 추가로 기존 질문과 유사한 느낌의 질문이 있어서 링크 첨부 드립니다!위의 링크드린 질문 답변에도 있지만 이 방식이 제가 선호하는 구현 방식은 아닙니다그저 지금 상황과 규모에 맞는 적절한 구현 전략을 선택한 예시를 보여드리고 생각을 해보시게 만들어드리고 싶었습니다 😃++ 트랜잭션에 대해서는 추가로 적어두면 Service 하나에 트랜잭션 하나로 묶는 것은 경우에 따라 역으로 비효율이 발생할 수 있습니다 (너무 길고 큰 트랜잭션일 경우 + 내부에서 외부 통신으로 Tran 시간이 길어지고 커넥션을 과소비하는 등)그래서 이것 자체가 트레이드 오프가 될 수 있다고 봅니다,개인적으로 저는 Service 함수에 Transaction을 무조건 or 쉽게 거는 것을 선호하지는 않습니다!(그래서 Controller 에서 이 구조와 Transaction은 크게 관여가 없는 전략이라고 봐주셔도 될 것 같습니다! 또 우리 강의 예제 규모에서는 신경쓸 수준이 아니라고 보여지구요!) [질문2]유즈케이스 라는 관점으로 봐도 크게 문제는 없을 것 같은데요! 지금 강의 기준으론 각각의 개념이 요구사항을 충족하기 위한 기능을 제공하고 있는 것이라고 이해해주시면 될 것 같습니다!사실 이 강의 규모에서는 잘 정리된 느낌의 유즈케이스라던가, Aggregation이라던가 를 논하기엔 너무작은 규모+혼란스러운+요구사항이 너무 빈약한형태라 생각합니다 😃가령 ProducSectionService 함수 하나를 유즈케이스로 보기엔 미묘한 부분이 있다고 봅니다 [질문3]일단 제가 바라보는 기준과 구현 전략에서는 대부분의 경우 Service 에서 다른 Service 를 호출하게 하지 않습니다위의 유사 질문의 답변에도 있지만 저는 방법1,2 둘다 아닌 Service -> 구현을 위한 도구들을 호출하는 방식으로 작업하는 것을 선호합니다 (당연히 무조건은 아니고 대부분의 경우입니다)이것 관련해서는 지속 성장 가능한 소프트웨어를 만들어가는 방법 이라는 제가 작성한 블로그 글과 인프런 무료강의 가 있으니 궁금하시면 봐보셔도 좋을 것 같습니다! ++ 추가로 어느 정도 규모의 서비스를 운영중이신지는 제가 잘 몰라서 조심스럽지만 제 의견을 적어보면모듈별이라는 의미가 만약 멀티모듈의 모듈이라면 조금 과한 구조가 아닐까 싶단 생각이 들었습니다!제가 상상하는 구조라면 적절한 응집이 구성되지 않은 형태일 것 같이 느껴집니다 🤔(이건 제가 상황을 잘 모르고 한 말이니 그냥 지금 제가 가진 정보 기준의 잘 모르는 사람이 말하는 느낌이라 봐주시면 될 것 같습니다 😃 아니라면 참 다행이에요!)추가적으로 질문 주신 것들에 대한 의도와 느낌과 고민은 뒷 강의들을 들으시다보면 더 혼란을 느끼시면서 생각이 정리 되실 수 있을 것 같습니다, 종류별로 구현체를 뒤죽박죽 해두었거든요! 😃모쪼록 시작하시는 시점에 혼란을 충분히 느끼고 계신데 아주 좋다고 봅니다!지금 상태에서 약간이나마 답이 되었길 바라며 완강까지 화이팅입니다!추가 질문이 있다면 편하게 주시길 바랍니다! - 1
- 1
- 31
 
- 질문&답변 - OrderService에서 조회에 트랜잭션 걸어준 이유가 있을까요? - 헉! 이 부분은 완전히 제 누락이네요ㅎㅎㅎ;;그치만 이렇게 또 한번씩 고민 해보실 수 있는 소재로써 이스터 에그 느낌으로 둬보도록 하겠습니다 😅해당 함수에서는 트랜잭션이 불필요합니다!추후 수정이 가능하면 반영하겠습니다!제보 감사드립니다! 👍👍👍👍👍👍 - 1
- 2
- 51
 
- 질문&답변 - findSections질문 - 안녕하세요! 질문 감사드립니다이 부분은 기존에 ProductSectionService 가 ProductFinder 를 사용하고 있습니다이걸 말씀해주신 옮긴 후를 보시면 ProductSectionService 가 ProductSectionRepository 만 알게 되는 형태가 됩니다또한 ProductFinder 도 기존에는 Product, ProductCategory, ProductSection 세 개의 Repository 를 알고 있었는데 이 수정 이후에는 Product, ProductCategory 두 개의 엔티티만 접근하는 형태가 됩니다해당 강의 10:29 쯤 설명이 나오듯 이 변경 자체로 인해 ProductFinder 는 더 Product 개념 기준의 응집 된 엔티티만 알고있는 형태가 됩니다!이 관점에서는 ProductSection 은 Product 랑 가깝지 않다 (상세 노출을 위한 메타 정보이므로 라는 논리) 가정을 하고 수정을 해보는 것 입니다!이런 느낌을 느껴보시려면 수정 후 수정 된 클래스들이 생성자, Import 를 한번 훑어보시면 서로 관계가 어떻게 변했는지 느낌을 느껴보실 수 있을 것입니다!추가로 궁금하신 것이 있다면 편하게 또 질문 주십쇼!모쪼록 답이 되었길 바랍니다! 감사합니다! 😃 - 1
- 2
- 36
 
- 질문&답변 - 날짜 수정 - 안녕하세요! 질문 감사드립니다!실제로는 더 다양한 이유가 있겠지만 가장 직관적인 이유들만 짚어보면 아래와 같습니다!(사실 제가 불편하다고 표현 했지만 정확히는 유지보수성이 좋지 않다에 가까운 것 같네요!)만약 해당 날짜 정보가 정책이라서 여러군데에서 사용하고 있는 기준 값일 경우 파라미터에 직접 넣는 것으로는 요구사항에서 날짜 정책 수정이 생길 경우 n개의 지점을 수정해야하는 문제와, 수정 누락이 발생 할 수 있는 문제가 있습니다그러므로 이런 불편함(유지보수성의 불편) 때문에 minusDays 직접 쓰는 것 보다는 상수를 추출해서 사용하는게 좋을 것 같습니다날짜를 파라미터에 순수하게 넘기면 당장 코드 작성자는 이해하기 쉬우나, 추후 시간이 지나면 코드 작성자 포함, 다른 팀원이 수정하려할때 이 날짜 값이 뭔지 의미 자체가 헷갈릴 수 있습니다그러면 수정하기 두려워지게 될 것 같구요! 그래서 이것 또한 상수 추출을 해서 사용하는게 좋을 것 같습니다!요런 이유로 불편함이라는 느낌으로 표현했는데 설명이 조금 부족했던 것 같네요!모쪼록 답이 되었길 바랍니다! 완강까지 화이팅입니다! - 1
- 1
- 34
 
- 질문&답변 - CouponService에서 이미 다운로드 한 쿠폰 안 내려주기 - 코드를 수정해보시고 고민하고 계시다니 아주 멋집니다!! 👍👍👍👍👍[포인트1]우선 현재 Controller 에 User 를 추가하면 인증된 사용자만 받아오게 됩니다!인증 기능 자체는 강의 초반에 저희 상황에서 설명드린 G/W에서 User Service를 호출하고 API Server로 넘어온다고 봐주시면 될 것 같습니다!코드로는 UserArgumentResolver 참고하시면 될 것 같구요! [포인트2]고민을 꽤 하고 계신 것 같은데 이걸 이해해보시면 좋습니다!ProductController의 findProduct 메서드에서 쿠폰을 불러오는 부분 위에 주석으로 처리해놓으신 것처럼 별도의 API를 만들고 해당 API에서 User를 활용해서 진행하면 어떨까이것도 가능하겠죠! 사실 이것과 별개로 이 요구사항에는 숨은 문제가 있습니다! 바로 비회원과 회원 모두 상품상세를 볼 수 있어야 한다는 것 입니다이 숨은 요구사항이 지금 구현에서 왜 문제가 발생할까요?왜냐면 UserArgumentResolver 의 구현을 보시면 인증 토큰이 없으면 예외를 던지고 있습니다이 말은 비회원은 처리할 수 없도록 만들어 둔 것입니다 😱 고로 상품상세 API에 User 를 추가하고 비회원이 상품상세를 보면 저 예외가 발생한다는 것 입니다![포인트3]그럼 어떻게 해야할까요? 상황에 따라 다르고 정답은 없지만 저는 보통 이럴때 UserOrGuestArgumentResolver 같은 리졸버를 추가하기도 합니다 그러면 회원/비회원 모두 한개의 API('상품상세 API' 나 '쿠폰 별도 API' 무엇으로 풀려고해도 이 문제는 동일하게 발생함)로 처리할 수 있을 것 같습니다!이것에 대한것은 한번 직접 풀어보시면 좋을 것 같습니다 😃해보시고 잘 모르시겠으면 다시 질문해주세요! [별첨..?]획기적인 아이디어로는 API 를 회원/비회원 나누고 클라이언트한테 로그인 상태따라 API를 호출하라 할 수도 있을텐데...... 이건 양쪽 모두 괴로운 일이 되겠죠ㅎㅎ모쪼록 느낌이 잘 전달 되었으면 좋겠습니다! 수정 많이 해보시고 고민 많이 해보셔요! 완강까지 쭉쭉 화이팅입니다!감사합니다! 😃 - 1
- 1
- 47
 
- 질문&답변 - 프로덕트와 카테고리에 대한 질문 - 앗!? 제가 혼동을 드리게 설명한 부분이 있으려나요? 음...... 저도 재검토를 해보겠습니다질문만 보고 이해해보면 아마 요구사항 부분에서는 카테고리를 누르면 상품이 나오는 형태기 때문에 카테고리안에 상품이 있는 형태라고 설명했을 것 같습니다! (저도 다시 확인은 해보겠습니다만 어느 강의에서 혼동이 있으셨는지 알려주시면 감사하겠습니다!)그런데 실제 구현에서는 요구사항을 반드시 구현에 그대로 투영할 필요가 없고 우리가 개발자로써 정의할 수 있는 부분이라는 것을 설명 드리고 싶었습니다고로 ProductCategory 에 대한 정의도 상품과 카테고리 중 "무엇을 더 중요하게 생각하고 무엇을 더 급이 높은 개념으로 정의할 것인가?" 를 우리는 요구사항과 별개로 고민하고 정의할 수 있어야합니다!그런 관점에서 구현에서는 Product 가 더 중요한 개념이라고 정의하였고 그래서 프로덕트의 카테고리를 ProductCategory 란 개념으로 지정한다고 표현하였습니다!모쪼록 답이 되었길 바랍니다! 추가 질문은 편하게 부탁드립니다!완강까지 힘내주세요! 감사합니다! - 1
- 2
- 51
 
- 질문&답변 - 강의를 보고 궁금한 것 질문 드립니다! - 안녕하세요! 또 질문 주셔서 감사합니다!1.맞기도하고 아니기도합니다ㅎㅎ 우선 Service 참조를 막기 위한 것은 의도가 아예 없는 것은 아니지만 부수적인 이득이라고 생각하구요!근본적으로는 포인트 사용 자체는 비즈니스성 보다는 타 비즈니스에서 활용 되는 목적이기 때문에 Service 레벨의 구현 보다는 구현체 자체로 존재하여 활용도가 높게 존재하고자 하는 의도가 제일 중요한 의도입니다!부가적으로 적어주신 것 처럼 여러 개념에 걸쳐있으면 재사용성/응집이 좋은 경우가 많습니다!다만 유의해야 할 것은 단순히 여러 개념에 걸쳐있다가 클래스를 분리하는 기준이 되면 안 될 것 같습니다!클래스 분리는 역할과 책임 관점에서도 적절한가? 과하지 않은가? 에 대하여 검토한 후 쪼개는 방향이 좋을 것 같습니다!(개념과 격벽은 요구사항과 코드를 융합하여 나타내는 형태인 것이지, 반대로 개념과 격벽 기준으로 코드가 작성 되면 안되는 느낌이라 봐주셔도 좋습니다!)2. 요구사항에 따라 다를 것 같지만 적립 정책이 복잡해지고 동적으로 처리 되어야한다던가하면 자연스럽게 클래스 추가는 괜찮을 것 같습니다!모쪼록 답이 되었길 바라며 완강까지 화이팅입니다!수강평도 기대하겠습니다! 감사합니다! - 2
- 2
- 73
 
- 질문&답변 - 금액 계산은 서버에서하고 클라이언트는 가격 정보를 주지 않았을 때 - 안녕하세요 질문 감사합니다!일반적인 경우에는 크게 문제가 없습니다! 물론 장바구니 화면을 오래 켜두다가 클릭해서 들어갈 수 있지만, 주문 화면으로 넘어오면 주문 금액이 있기 때문에 고객이 이상하다면 충분히 눈치를 챌 수 있을 정도인 것 같습니다!(주문 후엔 이미 금액이 스냅샷으로 박혀있기 때문에 주문화면에서 늦게 결제하는건 당연히 문제 사항아님)다만 이런 일이 많거나 미묘한 금액 차이도 발생 시 문제가 클것으로 예상 된다면 클라이언트가 금액을 보내주면 금액 검증 전용 로직을 추가해둘 수 있을 것 같습니다추가로 버저닝을 하는 형태나 단순 검증 로직 이상의 복잡도는 대부분의 서비스에선 불필요할 것으로 예상됩니다! (주객전도가 아닌지 검토가 필요해 보입니다!)단순히 클라이언트가 totalAmount 를 보내면 서버에서도 Order 생성 시 totalAmount 를 비교해서 금액이 다르면 에러를 던져주면 되는 것 이니까요!모쪼록 답이 되었길 바랍니다! 감사합니다! - 1
- 3
- 79
 
- 질문&답변 - 어떤 경우 도메인(개념)객체를, 어떤 경우 JPA 엔티티를 활용하나요? - 안녕하세요! 질문 감사합니다!사실 강의에서 언급하였지만 일부로 큰 혼란을 느끼시라고 구현 패턴을 다양하게 넣어두었습니다 😄판단 기준은 회사마다 팀마다 전략이 다를 수 있는 부분이라서 정답이 있는 것은 아닙니다!그럼에도 제 판단 기준을 말씀드리면 저는 회사/팀의 역량 수준이 중요한 판단 기준입니다같이 일하는 동료들의 역량이 조금 아쉽다면, 약간의 경직 된 룰을 만들어서 팀을 유도합니다(경직 된 룰 = 무조건 Finder 같은 도구를 만들어서 처리하자)* 물론 이 수준을 영원히 유지하지 않습니다 팀원들이 어느정도 도메인에 익숙해지고, 구현에 익숙해진다면 좀 더 유연한 룰로 변경해나가는 것을 진행하는편입니다.만약 베스트 팀이라면 제 경우는 소프트웨어가 성장하는 시점에 맞추어서 성장시키는 것을 선호하기 때문에 굳이 과하게 만드는 방향으론 개발을 하지 않습니다(다만 제 커리어상으로도 회사에서 이렇게 할 수 있는 팀을 만난 것은 딱 한번 정도 같습니다 ;ㅁ; 현실적으로 어렵습니다......)그럼으로 repository 를 그냥 직접 쓰게하기도 하죠 (애초에 베스트 팀원들 상황이라면 서로 알아서 잘 할것이기 때문에 걱정 자체가 없습니다ㅎㅎ..)종합적으로 보면 정해진 것은 없고 강의 예제에서는 일부로 혼란을 느끼시도록 유도했습니다ㅎㅎ 그러므로 직접 코드를 느껴보시면서 어떤 전략이 더 유효 할지 어떨때 저 전략을 써야할지 고민해보시는게 더 중요할 것 같습니다! 😄모쪼록 답이 되었길 바랍니다! 감사합니다! - 1
- 3
- 111
 
- 질문&답변 - 목록 조회에서 개념(도메인)객체를 반환할 때 - 안녕하세요 질문 감사합니다!이건 사실 실무에서 딱 정해진 전략보다는 회사/팀 별 선호하는 스타일이 있는 편 인것 같습니다!(결국 1,2번 모두 트레이드 오프가 있는데요 클래스가 계속 늘어나게 할것이냐, 개념 객체가 일부 데이터가 비어있는걸 허용할것이냐의 문제(불완전한 상태로 돌아다님))그치만 저는 일반적으로 1번, 2번 모두 선호하지 않습니다!왜냐면 1번의 경우는 자칫하면 Web, APP의 요구사항을 맞추기 위한 클래스가 계속 무수히 생기는 경향을 만들 수 있기 때문입니다2번은 당연히 개념객체가 어떨때는 채워져있고, 어떨때는 비어져있고 이건 예측 가능성을 떨어트리기 때문에 좋은 선택지가 아니라고 생각합니다그래서 저는 가급적 개념 객체를 다 채우는 것을 선호합니다, 그리고 개념에 대한 클래스들이 잘 생성 되어있다면 대부분의 경우 데이터 조회 후개념 객체의 필드를 다 채우는 것이 그렇게 큰 비용이 아닐 것 입니다.그래서 Service 영역에서 리턴할 경우는 개념객체를 리턴하도록하고, 만약 API에 일부 필드만 응답 해야한다면 그건 Controller(Presentation Layer) 에서 처리하도록 구현하는 편 입니다!그리고 만~약 클래스를 추가한다 하더라도 그 기준이 개념의 응집도를 최대한 우선 시 하는 편입니다! (Page 응답을 위한 DTO 클래스를 만드는 것 전에 한번 응집에 대해 검토한다는 의미)다만 이건 제가 더 선호한다는 것이지 1번,2번 모두 틀린 것은 아닙니다!실무에서는 이것에 대해서 굉장히 회사마다 팀마다 다른 전략을 선택하기에 한가지 전략은 아니라고 봐주시면 될 것 같습니다!모쪼록 답이 되었길 바랍니다! 감사합니다! 😃 - 1
- 3
- 61
 





