🚀들어가며
Reactive Programming을 학습하다 보니, 늘 서비스의 확장 가능성을 고민해야 하는 입장으로서 지금 당장 쓰지는 않더라도 확실하게 내용을 정리해야겠다는 생각이 들었다.
이전에 포스팅했던 넷플릭스의 Zuul 2 도입기에서 기존 블로킹 코드와의 충돌 부분을 흥미롭게 읽었는데,
Webflux에서도 JPA의 트랜잭션이 블로킹이 적용된 코드이므로 연동을 지원하지 않는다는 내용을 보고 왠지 뿌듯했다!
그럼 바로 본론 시작~
참고로 아래 작성한 프로젝트는 회원이 커피를 주문하고, 스탬프를 적립받는 시스템의 일부다.
커피를 주문하면 스탬프를 찍어주는 기능이 있다보니 회원정보에 스탬프 필드가 들어가 있다.
그 외에 기본적인 CRUD는 보편적인 방식으로 구현했으나, 궁금한 점이 있으시면 댓글 달아주시길!
1️⃣Webflux 사용을 위한 사전 설정
build.gradle
application.yml
DB.Schema
Spring application. class 설정
2️⃣Controller구현과 특징
- @RequestBody 를 Mono 래핑
- 바로 오퍼레이터 체인 적용 가능
- reactor의 mono.오퍼레이터() X requestbody.오퍼레이터()O
- 모든 데이터 객체를 Mono, Flux로 래핑
- 응답객체는 보통 하나이므로 mono를 자주 쓴다
- PageRequest객체를 컨트롤러에서 미리 생성
- 시퀀스 내부에서 재사용되어야 하므로!
- 리턴되는 데이터가 없는 경우 Mono<void>
3️⃣Entity 구현과 특징
- Spring Data family 프로젝트의 최소 설정만 포함해야 함
- 기본 지원 Auditing 기능 활용 가능
- @CreatedDate, @LastModifiedDate
- @Id
- 외래키 갖는 엔티티 클래스는 직접 해당 클래스에 추가해줘야 함
- R2DBC는 애너테이션, 컬렉션을 이용한 연관관계 매핑 지원하지 않음
- 내부적으로 블로킹 요소가 포함될 가능성이 있기 때문→라이브러리 사용시에도 주의!
4️⃣Service 구현과 특징
의존성 주입, createMember()
- R2DBC의 데이터 접근방식
- Repository방식
- R2DBC가 지원하는 SQL 쿼리 빌드 메서드 방식
- 모든 데이터 객체가 mono, flux 타입이므로 바로 오퍼레이터 체인 연결
- then() 오퍼레이터
- 이전에 동작하던 시퀀스를 종료(verify~ 시퀀스인듯)
- 새로운 시퀀스 시작
- 자동 인식을 지원하지 않으므로 직접 repository나 쿼리 코드 짜야 함
- ex: R2dbcEntityTemplate. insert()
- 반드시 코드 마지막에 subscribe() 호출해야 함
updateMember()
- switchIfEmpty(퍼블리셔) 오퍼레이터
- emit되는 데이터가 없다면 파라미터가 대체 동작 수행
- BeanUtils.copyNonNullProperties(member, findMember)
- 첫 파라미터에 들어온 데이터 중 null이 아닌 값만
- 두번째 파라미터(db조회한 값)에 반영
findMember(), findMembers()
- collectList() 오퍼레이터
- 리스트로 변환해 emit
- 호출한 오퍼레이터.zipWith(파라미터 Mono)
- 호출한 오퍼레이터의 Mono와
- 파라미터 Mono를
- Tuple2 객체로 결합해서 전달
- new PageImpl<>(데이터1, 페이지리퀘스트, 데이터2)
deleteMember()
- R2dbcEntityTemplate.delete(SQL쿼리빌드메서드체인 )
- 외래키로 관계를 맺는 테이블의 경우
- 외래키가 있는 쪽에서 외래키 먼저 삭제
- 이후 기본키 쪽 삭제
5️⃣Repository 구현과 특징
- R2dbcRepository
- CRUD,페이지네이션, 정렬기능 모두 포함함
👏나가며
기존에 익숙하게 사용하던 JPA에서 지원하던 기능들이 사라지면서 확실히 기초가 탄탄해야 함을 느꼈다. 특히 템플릿 부분이 잘 기억이 안 나서 복습이 필수라고 체감했다...
또, 넷플릭스에서 Zuul2를 도입하면서 기존의 블록킹 코드를 찾아내고, 변경하느라 애를 먹었다는 내용이 끊임없이 강조되는 걸 보면서(ㅋㅋㅋㅋ) 어떤 기술을 사용할 때 장점만을 기대하며 도입해서는 안 되겠다는 교훈을 얻게 되었다. 넷플릭스 오픈소스인 Zuul2의 코드는 어떻게 구현되어 있을지 분석하는 포스팅도 작성해보고 싶다.
'Web > Spring' 카테고리의 다른 글
Error Handling w.Spring: 꼼꼼하고 효율적인 예외처리는 어떻게 만들어질까? (2) | 2023.01.26 |
---|---|
Spring Security의 간장공장공장장😱 Authentication? Authorization? Provider? Manager? FilterChain? 쉽게 정리하자 (0) | 2022.10.23 |
(번역)넷플릭스의 Zuul 2 도입기를 통해 보는 Non blocking의 장단점, blocking 쉬운 설명 (1) | 2022.10.15 |
DTO란? DTO 정적 이너 클래스로 만드는 이유(캡슐화, 속도) (0) | 2022.10.12 |
세션 vs 토큰, JWT 구조와 취약점 (0) | 2022.10.11 |