-
여태까지의 게시글을 통해 대충 WebFlux의 구현체나 동작 방식에 대해 알아보았다.
그럼 이제부터는 실전으로 MVC 패턴과 비교해가며, 무엇이 다르고 어떻게 다른지 알아보겠다.
우선 아래의 코드는 기존의 Spring MVC 패턴의 Controller이다.
Service와 mapper가 의존성으로 주입되어 있지만, 대충 코드만 보아도 어떻게 동작할지 눈에 보일 것이다.
@RestContoller@RequestMapping("/v1/test")public class MvcController{private final BookMvcService bookMvcService;private final BookMapper mapper;public MvcController(....){...}@PatchMapplng("/{book-ld}")public ResponseEntlty patchBook(@PathVariable("book-ld") long bookld,@RequestBody BookDto.Patch requestBody) {requestBody.setBookId(bookld);Book book = bookMvcServlce.updateBook(mapper.bookPatchToBook(requestBody));return ResponseEntlty.ok(mapper.bookToBookRespose(book));}@GetMapping("/{book-ld}")public ResponseEntlty getBook(@PathVarlable("book-ld") long bookld) {Book book = bookMvcServlce.flndBook(bookld);return ResponseEntlty.ok(mapper.bookToBookResponse(book));}}그렇다면 위의 코드가 WebFlux로 변환되면 어떻게 되는가?
반환 타입이 단일이라면 Mono, 여러개라면 Flux가 될 것이다.
@RestContoller@RequestMapping("/v1/test")public class Controller{private final BookService bookService;private final BookMapper mapper;public Controller(....){...}@PatchMapplng("/{book-ld}")public Mono patchBook(@PathVariable("book-ld") long bookld,@RequestBody BookDto.Patch requestBody) {requestBody.setBookId(bookld);Mono<Book> book =bookServlce.updateBook(mapper.bookPatchToBook(requestBody));return mapper.bookToBookRespose(book);}@GetMapping("/{book-ld}")public Mono getBook(@PathVarlable("book-ld") long bookld) {Mono<Book> book = bookServlce.flndBook(bookld);return mapper.bookToBookResponse(book);}}변경점은 BookService클래스에서 리턴하는 값들이 Mono<Book>이라는 것 과, 위의 핸들러 메서드 모두 Mono 타입을 리턴하는 것이 변경점이다.
여기서 문제점은 DTO 객체와 에티티 객체를 서로 변환하는 시점에서 Blocking 포인트가 존재한다는 것이다.
비록 짧은 시간이라지만, 그래도 Blocking 요소를 삭제하고 싶다면 아래와 같이 수정한다.
@RestContoller@RequestMapping("/v1/test")public class Controller{private final BookService bookService;private final BookMapper mapper;public Controller(....){...}@PatchMapplng("/{book-ld}")public Mono patchBook(@PathVariable("book-ld") long bookld,@RequestBody Mono<BookDto.Patch> requestBody) {requestBody.setBookId(bookld);Mono<Book> book =bookServlce.updateBook(mapper.bookPatchToBook(requestBody));return mapper.bookToBookRespose(book);}@GetMapping("/{book-ld}")public Mono getBook(@PathVarlable("book-ld") long bookld) {Mono<Book> book = bookServlce.flndBook(bookld).flatMap(book->Mono.just(mapper.bookToResponse(book)));}}Spring WebFlux에서는 핸들러 메서드의 메서드 아규먼트로 리액티브 타입을 지원한다.
따라서 postBook(), patchBook() 등의 핸들러 메서드는 Mono<BookDto.patch> 타입을 메서드 아규먼트로 전달받은 후 서비스 계층으로 전달한다.
getBook() 핸들러 메서드의 경우 서비스 계청의 findBook() 메서드로부터 리턴 값으로 전달받은 Mono<Book>을 이용해 flatMap() Operrator 내부에서 다시 DTO 클래스로 변환 함으로써 Blocking 요소를 제거한다.
사용한 Service
@Service........public Mono<Book> updateBook(final long bookId, Mono<BookDto.patch> book){return book.flatMap(patch -> {patch.setBookId(bookId); return Mono.just(mapper.bookPatchToBook(patch))});}public Mono<Book> findBook(long bookId){return Mono.just(new Book(bookId, "Java", "a"....))}updateBook()의 경우, Controller에서 전달받은 Mono내부에서 mapper를 통해 DTO 클래스의 객체를 엔티티 클래스로 변환한 후 return만 처리해주고 있다.
findBook의 경우 더미 데이터를 리턴 한다.
'개발 > 스프링 WebFlux' 카테고리의 다른 글
스프링 부트 - WebFlux의 Non-Blocking 프로세스 구조 (0) 2025.01.09 스프링 부트 - WebFlux 핵심 컴포넌트 (0) 2025.01.09 스프링 부트 - WebFlux 처리 흐름 (0) 2025.01.09 스프링 부트 - Spring WebFlux 개요 (0) 2025.01.08