-
카테고리
-
세부 분야
백엔드
-
해결 여부
미해결
Mono 의 정의를 잘 모르겠습니다..
24.01.29 22:58 작성 24.01.29 23:37 수정 조회수 205
0
안녕하세요 문의 사항이 있어 글을 올립니다.
@PutMapping("/{userId}")
public Mono<User> updateUser(@PathVariable Long userId, @RequestBody UserUpdateRequestDto userRequestDto) {
return mainService.updateUser(userId, userRequestDto);
}
public Mono<User> updateUser(Long id, UserUpdateRequestDto userUpdateRequestDto) {
// 데이터베이스에서 사용자 조회
return dataRepository.findById(id)
.flatMap(existingUser -> {
// 기존 사용자가 있으면 업데이트 수행
existingUser.setName(userUpdateRequestDto.getName());
// 다시 데이터베이스에 저장
return dataRepository.save(existingUser);
});
}
과 같이 Mono<User> 를 리턴 하는데 포스트맨으로 응답이 json 형태로 옵니다.
저는 User를 리턴한게 아닌 Mono<User> 를 리턴한건데 어떻게 포스트맨이 별도의 처리 없이 Mono 안의 User 값을 받을 수 있나요?Mono<User> userMono = webClient.get() .uri("/user/{id}", userId) .retrieve() .bodyToMono(User.class);
위와 같은 코드를 보았는데 이 경우 Mono<User> userMono
로 받게 되던데 결국 리턴은 Mono<User> 가 맞는거 같은데
포스트맨이 어떻게 User 값을 바로 가져다 썼는지 이해가 잘 안가서 질문 올립니다.
+ 추가로 mono나 flux는 subscribe()를 해줘야 동작을 한다고 하셨었는데 subscribe()를 적지 않았는데 어떻게 update가 동작한건지 궁금합니다.
![course-thumbnail](https://cdn.inflearn.com/public/courses/325963/cover/a294b047-11e0-48fa-babc-13da48609f6c/325963-eng.png?w=240)
Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
Cold Sequence & Hot Sequence 이해하기
강의실 바로가기
답변을 작성해보세요.
1
Kevin
지식공유자2024.01.30
안녕하세요?
두 가지 질문을 주신걸로 여겨지는데요.
주신 질문에 간단하게나마 답변을 드리도록 하겠습니다.
저는 User를 리턴한게 아닌 Mono<User> 를 리턴한건데 어떻게 포스트맨이 별도의 처리 없이 Mono 안의 User 값을 받을 수 있나요?
--> Postman 뿐만 아니라 Spring에서 지원하는 RestTemplate 같은 Rest Client를 사용해서 Spring WebFlux의 엔드포인트를 호출해도 응답 데이터를 전달 받을 수 있습니다. 즉, 말씀하신대로 Spring WebFlux의 엔드포인트에서는 Mono<User>를 리턴하지만 클라이언트 쪽에서는 json으로 전달 받을 수 있습니다.
이렇게 전달 받을 수 있는 이유는 Postman이나 RestTemplate 같은 클라이언트 툴이 Blocking I/O 방식으로 동작하기 때문인데요. 클라이언트 쪽에서 Non-Blocking I/O를 지원하지 않는다면 서버 쪽에서는 내부적으로 Blocking I/O 방식으로 동작한다고 보시면 될 것 같습니다.
어떻게 Mono<User>를 리턴 타입으로 지정했는데, json을 전달 받을 수 있는지에 관해서는 두 번째 질문과도 연관이 있는데요.
Spring WebFlux 프레임워크 내부에서 subscribe()가 호출이 되는게 맞습니다.
다만, subscribe()가 언제 호출되는지 시점의 차이가 있는데 RestTemplate 같이 Non-Blocking I/O를 지원하지 않는 Rest Client를 사용할 경우에는 서버 쪽 Spring WebFlux 내부에서부터 subscribe() 호출이 시작된다고 보시면 될 것 같구요.
Non-Blocking I/O를 지원하는 WebClient를 이용하면 WebClient 쪽 즉, 클라이언트 쪽에서 subscribe()를 호출해야지만 서버 쪽 엔드포인트를 호출합니다.
이 말은 subscribe() 호출 시작이 클라이언트에서부터 시작한다는 의미와 같습니다.
추가로 스프링웹 플럭스가 컨트롤러쪽으로 Mono 나 Flux 타입이 리턴되면 subscribe() 를 자동으로 해준다는데 이게 맞는말인지 궁금합니다
--> 위에서 말씀 드렸지만 Spring WebFlux 프레임워크 내부에서 subscribe()를 해준다고 보시면 되는데, Rest Client가 Non-Blocking을 지원하면 클라이언트 쪽에서 subscribe()를 호출 해야지만 서버 쪽에서도 subscribe()가 호출되어서 Reactor Sequence가 동작을 합니다. 테스트 해 보시면 아시겠지만 WebClient로 서버쪽 엔드 포인트를 호출해서 response body 응답을 mono로 변환하는 부분(bodyToMono()) 다음 코드 체인으로 subscribe()를 호출하지 않으면 서버쪽 엔드 포인트를 호출하지 않습니다.답변 드린 내용이 도움이 되셨으면 좋겠습니다.
감사합니다.
![verdelet님의 프로필](https://cdn.inflearn.com/public/main/profile/default_profile.png?w=48)
verdelet
질문자2024.01.30
안녕하세요 강사님
마지막으로 하나만 여쭤 봐도 될까요..?
강의에서 책 조회 서비스를 예를 드셨었는데
유저(클라이언트가) 책 조회를 하게 되면 본 서버가 하위 서버에게 각각 책이 있는지 조회를 요청 하는
그림을 보여주셨었는데 본서버는 webclient로 하위 서버에게 Non-Blocking 비동기요청을 하게되고
하위 서버는 웹플럭스를 사용하여 응답을 줘서 Non-Blocking 리액티브 비동기가 맞다고 생각을 했습니다.
하위 서버로 부터 조회정보를 받은 본 서버는 유저에게 이제 응답을 줘야하는데
유저에게 주는 응답은 blocking 방식으로 줘도 되는것이 맞는지 궁금합니다.
만약 비동기 Non-Blocking 로 응답을 줘야 한다면 유저가 도서 조회 버튼을 누를때 비동기로 요청 되도록 fetch 같은걸로 요청을 해야하는 건가요..?
늦은 시간에 답변 주셔서 감사드립니다.
Kevin
지식공유자2024.01.30
네, 클라이언트 쪽에서도 Non-Blocking을 지원해야 Fully Non-blocking하게 동작합니다.
그래서 Spring WebFlux에서는 RestTemplate을 사용하는 것 보다 WebClient를 사용하는 것을 권장하고 있습니다. 적은 트래픽에서야 큰 차이가 나지 않을 수 있지만 대량의 트랙픽이 발생할 경우에는 Blocking 포인트가 늘어나는 만큼 성능에 악영향을 미칠테니까요.
그래서 Non-Blocking 애플리케이션에서 내부적으로 Blocking call이 발생하는 구간이 없는지를 점검하는 blockhound 같은 오픈 소스도 존재합니다.
Kevin
지식공유자2024.01.30
`하위 서버로 부터 조회정보를 받은 본 서버는 유저에게 이제 응답을 줘야하는데
유저에게 주는 응답은 blocking 방식으로 줘도 되는것이 맞는지 궁금합니다.
만약 비동기 Non-Blocking 로 응답을 줘야 한다면 유저가 도서 조회 버튼을 누를때 비동기로 요청 되도록 fetch 같은걸로 요청을 해야하는 건가요..?
`
--> 최종 클라이언트 즉, 사용자인데요. 사용자에게 Blocking 방식으로 응답을 주든 Non-Blocking 방식으로 주든 애플리케이션이 서비스를 제공하는데 문제가 없는지 상황에 맞게 분석 또는 테스트해 보시고 결정하시면 됩니다. 다만, Spring WebFlux를 사용하는 근본적인 이유는 대량의 트래픽을 효과적으로 처리하기 위해 Fully Non-Blocking하게 동작하도록 하는 것이라서 Blocking call이 최대한 개입되지 않도록 하는게 맞다고 생각합니다.
사용자 쪽이 javascript를 사용하는 웹 앱을 말씀하시는 것 같은데 fetch API를 사용하시면서 async로 동작하게 해도 되지만 Javascript에서 rx.js 같은 라이브러리를 이용하면 데이터 처리를 조금 더 효과적으로 처리할 수 있다고 생각합니다.
답변 1