대머리개발자

reactive 리팩토리.. 본문

개발이야기/자봐

reactive 리팩토리..

대머리개발자 2023. 8. 4. 10:38
728x90

모든 비지니스 로직이 하나의 흐름에 들어가야 하는 것이 맞는건가??

결과는 같지만 정확한 이해를 위해서 다시 한번 곱씹어 봤다.

 

반년전에 작성했던 코드를 다시 보니.. @.@

 

 

1. 적절한 리액티브 연산자를 사용자.

Reactive는 흐름을 만들어서 데이터의 조작한다.
기본적으로 flatMap( .. )으로 흐름을 이어주는 즉, 만들어주는 친구다.

예를 들어  보자.

   return existsById(user.getId())
                .flatMap(isOk -> ServiceUtil.getRedisService().delOpsForValue(Constants.REDIS_USER + user.getId()))
                .flatMap(isOk -> userRepository.updatePassword(user.getPassword(), user.getId()))
                .flatMap(just -> getUser(user.getId()));

 

1. 사용자가 있는지 체크하고

2. 레디스 정보 지우고

3. 사용자 업데이트 하고

4. 사용자 다시 조회 한다.

 

::

여러개의 flatMap을 하나의 flatMap으로 진행해도 무방하지만 코드의 가독성을 위해서... 어떤코드가 더 좋은지는..?..

어쨌거 최종 전달하는 데이터는 사용자다. 중간중간  무의미한 코드가 보인다.

아래와 같이... and()로 조지고 then()으로 고고싱한다.

 return existsById(user.getId())
                .and(ServiceUtil.getRedisService().delOpsForValue(Constants.REDIS_USER + user.getId()))
                .and(userRepository.updatePassword(user.getPassword(), user.getId()))
                .then(getUser(user.getId()));

 

 

2.  Join이 맞는건지... 두번의 쿼리가 맞는건지..

public Mono<UserGrpc.User> getSimpleUser(String userID){
        return ServiceUtil.getUserRoleService().searchUserRoles(userID)
                .collectList()
                .flatMap(userRoles ->
                                     userRepository.findById(userID)
                                            .switchIfEmpty(Mono.defer(()->Mono.error(new DefinedException("user info is null"))))
                                            .flatMap(user -> {
                                                UserGrpc.User userWithRole = user.toProtoWithRoles(userRoles);
                                                return ServiceUtil.getRedisService().setOpsForValue(Constants.REDIS_USER + userID, ObjectUtil.getObjectToJsonByGson(userWithRole))
                                                        .then(Mono.just(userWithRole));
                                            })
                );
}

 

1. 사용자의 Role을 불러와서 List로 만들고

2. 사용자를 불러와서 Role를 적재하고

3. 레디스 저장하구 리턴S

 

:: 가만히 보면 Role을 포함한 한방 쿼리를 통해서 사용자를 조회 할 수도 있다.

 

물론 R2DBC가 JPA처럼 성숙한 친구가 아닌것이 일차적인 문제이긴 하지만 @Query( .. )를 지원해 주니.. 테스트 해 볼만한 가치가 있다고 생각한다. 한방 쿼리가 된다면 로직이 심플해 질 수 있다.

 

정답은 없다... 정답인척하는 근거만 찾자잉.. 물론 그 근거가 뒤집힌다고 해서.. 좌절한것도 없다..

 

3.  따로따로 해도 되는건지...

 

모든 비지니스 로직이 하나의 흐름으로 처리 해야 하는건지?

아니다.!!

 

 

1. 데이터를 발행하고

2. 데이터를 가공하고

3. 구독에서 처리하규

:: 이것이 하나의 Set이다.

 public void update(UserGrpc.User request, StreamObserver<UserGrpc.User> responseObserver) {
        ServiceUtil.getUserRoleService().delete(request.getId()).subscribe(); // 기존 삭제 로직

        request.getRolesList().forEach(role ->
                ServiceUtil.getUserRoleService().create(UserRole.builder().userId(request.getId()).roleName(role.getRoleName()).build())
                        .subscribe()
        );

        subscribe(ServiceUtil.getUserService().update(toDto(request)), responseObserver);
    }

 

1. 기존의 Role 삭제하고 

2. 새로운 Role 등록하고

3.  사용자 업데이트 하구


각 비지니스 역할마다 데이터 발행/가공 -> 구독처리를 하는 것이다.

 

즉,, 각각의 로직에서 흐름만 가주가면 될듯 하다.

728x90

'개발이야기 > 자봐' 카테고리의 다른 글

Armeria 프레임워크 - 리다이렉트(2)  (1) 2023.10.06
flatMap vs Map  (2) 2023.09.15
jib 이용한 컨테이너 배포  (0) 2023.07.25
로또플줵 - 끝이(?)  (0) 2023.06.19
간단 로그인 프로세스  (0) 2023.06.15