Spring & Springboot

[스프링/Spring] 연관관계를 갖는 DTO를 엔티티로 저장할 때 고민

💡 문제 상황 만들어보고 있는 프로젝트에서는 '유저', '게시물', '카테고리'라는 도메인이 존재합니다. 이 때 유저와 게시물은 일대다관계, 카테고리와 게시물도 일대다관계를 가지고 있는데요. 다른 도메인이나 서비스에 대한 로직은 차치하고 말씀드리겠습니다. 문제가 되는 상황은 사용자가 게시물을 작성하는 상황에서 발생했는데요. 아래는 게시물 작성과 관련된 Controller, Service, Post 엔티티, PostSaveDTO입니다. PostSaveDTO는 게시물을 작성할 때 JSON 데이터를 객체로 입력받아 서비스 로직에 던져지는 녀석입니다. 문제는 어떤 사용자가 게시물을 작성한다고 가정했을 때, Json 형태로 받아올 수 있는 정보는 유저 정보, 카테고리의 아이디, 게시물의 제목과 내용이라는 점에서 ..

2021.10.03 게시됨

Spring & Springboot

[스프링/Spring] @OneToMany/@ManyToOne 연관관계에서의 Infinite Recursion 문제를 DTO로 해결하기

🧐 문제 상황 투표 기능 API를 만들다가 마주했던 문제인데요. 아래와 같이 Vote, VoteOption이라는 두 개의 도메인이 존재합니다. Vote 도메인은 '투표'라는 엔티티를 의미하며 어떤 게시물(Post)에 종속되어 있고 여러 개의 투표 항목 옵션(VoteOption)과 일대다 관계로 매핑되어 있습니다. 하나의 투표에는 선택할 수 있는 투표항목이 여러 개 존재하기 때문이죠. 그리고 VoteOption은 한 개의 Vote에 여러 개가 존재하므로 @ManyToOne 어노테이션으로 Vote를 참조합니다. 이 상황에서 "어떤 게시물에 존재하는 투표를 조회하는" API를 작성하려고 합니다. Request-Header로 조회한 유저의 아이디를 받고, 게시물의 아이디와 투표의 아이디를 PathVariable..

2021.09.28 게시됨

Spring & Springboot

[스프링/Spring] @Controller 그리고 @RestController

📖 문제 오늘은 프로젝트에서 어떤 아이템들을 분류하기 위한 카테고리를 생성하는 코드를 짜다가 마주한 문제에 대해 글을 작성해보려고 합니다. 사실 이 글을 작성한 지 한 달이 좀 넘어서 부분적인 내용을 수정하고 있는데 @Controller와 @RestController의 차이는 정말 당연한 개념이지만 반드시 알아야 하는 개념인 것 같습니다. 아래 코드를 보면서 이야기해보겠습니다. @Controller @RequiredArgsConstructor public class CategoryApiController { private final CategoryService categoryService; // 등록 API @PostMapping("/api/category/add") public Integer save(..

2021.09.17 게시됨

Spring & Springboot

[스프링/Spring] DTO는 왜 써야 하나?

1. 고민? DTO(Data Transfer Object)란 계층간 데이터 교환을 위해 사용하는 객체입니다. 아래 코드를 보면서 DTO는 왜 필요한가에 대해 생각해보겠습니다. * 실제 간단한 엔티티 설계의 일부입니다. 위 예제 코드는 Posts라는 엔티티를 생성하는 코드입니다. 맨 처음에 PostsSaveReqeustDto라는 Dto 객체를 빌더 패턴으로 생성하고 Dto를 컨트롤러에게 던져줍니다. 컨트롤러는 해당 Dto를 다시 Service에게 넘겨주고, Service 딴에서 JPA를 이용하여 생성된 객체를 저장합니다. "그런데 DTO와 Entity는 거의 똑같은 것 같은데, 왜 변환을 해서 사용해야 하며, 그렇다면 언제 DTO가 필요할까요?" 2. 언제, 왜 DTO를? 몇 가지 책과 기술 블로그를 참고..

2021.09.07 게시됨

Spring & Springboot

[스프링(Spring)] @Autowired 조회 대상 빈이 여러 개일때는 어떻게 할까? (feat.NoUniqueBeanDefinitionException)

📒 들어가면서 의존관계 주입을 할 때 사용하는 @Autowired 어노테이션은 기본적으로 스프링 빈을 타입(Type)으로 조회합니다. 예를 들어 아래처럼 할인정책에 관한 내용을 담고 있는 discountPolicy에 대한 의존관계를 주입한다고 해봅시다. @Autowired private DiscountPolicy discountPolicy 이 때, discountPolicy 인터페이스에는 각각 다른 할인 정책을 구현한 여러가지 구현체들이 있을 것입니다(discountPolicy1, discountPolicy2,...,discountPolicyN). 만약 이 상황에서 아래와 같이 DiscountPolicy의 하위 타입인 FixDiscountPolicy, RateDiscountPolicy를 둘 다 스프링 빈..

2021.08.30 게시됨

Spring & Springboot

[스프링/Spring] 의존관계 주입(DI)은 어떻게 할 수 있을까? - 여러가지 의존관계 주입 방법

🧑‍💻 들어가면서 의존관계 주입은 객체 지향 설계를 하는 데 있어서 정말 중요한 개념이죠. 의존 관계 주입 없는 쌩 자바 코드만으로는 DIP, OCP 등의 객체지향 설계 원칙을 지키기 힘들고, 객체끼리 서로 의존할 수밖에 없는 상황이 발생하기 때문입니다. 의존 관계 주입이 왜 필요하고 무엇인지에 대한 내용은 이전에 정리한 글도 있으니 참고하실 분들은 참고하시면 좋을 것 같습니다. [스프링/Spring] 객체 지향 설계와 DI(Dependency Injection)의 시작(feat. 생성자 주입) 👻 0. 들어가면서 이전 포스팅에서 스프링이 만들어지고 각광받는 이유가 "객체 지향 프로그래밍의 장점을 극대화할 수 있기 때문"이라고 했다. 그리고 객체 지향 프로그래밍이란 '컴포넌트를 studyandwrite...

2021.08.25 게시됨

Spring & Springboot

[스프링/Spring] 싱글톤(Singleton) 패턴과 스프링 컨테이너

📖 싱글톤 패턴이란 무엇일까? 스프링은 기업용 온라인 서비스 기술을 지원하기 위해 탄생했고, 웹 어플리케이션은 보통 여러 고객이 동시에 요청을 보냅니다. 위와 같은 그림의 예시에서 세 명의 클라이언트가 동시에 어떤 요청을 보내게 되면, DI 컨테이너는 memberService를 생성해서 반환해줍니다. 하지만 이 상황에서는 고객의 요청만큼 객체가 계속 생성되고, JVM 메모리에 객체가 계속 쌓이는 문제가 발생합니다. 아래 테스트 코드와 결과를 통해 확인해보죠. public class SingletonTest { @Test @DisplayName("스프링이 없는 순수한 DI 컨테이너") void pureContainer(){ AppConfig appConfig = new AppConfig(); // 1. 조..

2021.08.23 게시됨

Spring & Springboot

[스프링/Spring] 스프링 컨테이너(Spring Container)와 스프링 빈(Spring Bean)에 대해 알아보자.

📚 0. 들어가면서 이전 포스팅에서 의존관계 주입(DI)가 왜 필요한가에 대해 예제 코드를 가지고 이야기해보았습니다. 궁극적으로 DI는 객체지향 설계의 원칙인 DIP와 OCP를 지키기 위한 노력에서 탄생했다는 것을 알 수 있었습니다. 이번 시간에는 예전에 자바로 작성했던 AppConfig를 스프링을 이용해 리팩토링해보고, 이 때 사용되는 스프링 컨테이너와 빈(Bean)의 개념에 대해 공부해보려고 합니다. 💻 1. 예제 코드 우선 아래처럼 자바 기반으로 작성한 코드가 있다고 해봅시다. MemberRepository는 멤버를 저장하는 데이터베이스이고 discountPolicy는 어떤 물건을 살 때 적용되는 할인 정책입니다. 그리고 orderService를 통해 멤버는 주문을 하게 됩니다. 지금은 AppCon..

2021.08.19 게시됨

Spring & Springboot

[Spring/React] CORS? CORS에러를 해결해보자

1. 들어가면서 CORS 에러는 누구나 한번쯤 만나보게 되는 고통스러운 문제입니다. 저 역시 인턴을 하면서 CORS 문제 때문에 하루종일 골머리를 앓았는데요. 이렇게도 해보고 저렇게도 해보고 하면서 결국 “프록시 우회”로 해결하긴 했는데, 그 시간을 되짚어보면서 정확히 CORS란 무엇이며 이로 인해 일어나는 에러를 어떻게 해결해야는지 정리해보려고 합니다. 2. 교차 출처 리소스 공유(CORS) 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 HTTP 헤더를 사용해서 한 출처에서 실행 중인 웹 어플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 무슨 말일까요? 만약 https://domain-a.com의 자바..

2021.08.13 게시됨

Spring & Springboot

[스프링/Spring] 객체 지향 설계와 DI(Dependency Injection)의 시작(feat. 생성자 주입)

👻 0. 들어가면서 이전 포스팅에서 스프링이 만들어지고 각광받는 이유가 "객체 지향 프로그래밍의 장점을 극대화할 수 있기 때문"이라고 했습니다. 그리고 객체 지향 프로그래밍이란 '컴포넌트를 쉽고 유연하게 변경'하는 것을 목표로 하며, 이를 위해서는 역할(인터페이스)과 구현(객체)을 분리하는 과정이 핵심이라고 설명했습니다. [스프링/Spring] 스프링(Spring)은 왜 만들어졌는가? 🏃 0. 들어가면서 정말 많은 기업에서 스프링을 쓰고 있다. 스프링이 무엇이길래, 어떤 점이 좋기에 개발 생태계에서 정말 중요한 프레임워크로 자리매김했을까. 이번 글에서는 스프링은 왜 만 studyandwrite.tistory.com 🤔 1. 객체 지향 프로그래밍을 위한 시도 자, 그렇다면 이제 "다형성을 활용해서 인터페이..

2021.08.08 게시됨