This post is about an experience at a customer engagement in which I had the opportunity to use an open source library from the Java Spring Framework with which I was not familiar. The customer has a ReactJS web client using a RESTful service as a controller. The web client needs to invoke services on the back end. However, for security reasons, the web client has no direct access to the back end, so the web client calls a controller REST API, which in turn makes a pass-through call to the back end service REST API.
I was tasked to provide a way for the web client to be notified of ongoing events taking place on the back end whenever a long-running multi-step process was invoked. Since Spring Boot was used for both the web controller and back end, WebFlux was chosen.
WebFlux is a module in the Java Spring 5 Framework. It internally uses Project Reactor and its implementation of the Publisher/Subscriber pattern Flux and Mono. Below is an example of how I implemented one-way push notifications between the web client and the back end service.
What makes this example different from the basic general use examples easily found on the web, is that this example is driven by actual customer requirements constrained by legacy architecture and security needs. The examples are shown and explained in three parts:
- A sequence diagram of the entire solution
- The back end service
- The web client controller
- The web client
Let’s now start with a look at the sequence diagram.
The diagram here shows the flow of the asynchronous subscribe/publish pattern of WebFlux.
- The web client opens and subscribes to the stream residing on the Restful web controller.
- The web client invokes the long running process through the web controller.
- The web controller invokes the long running process while it also subscribes to the additional stream residing on the back end service.
- The long running process publishes messages to the stream as notification events to which the web controller has subscribed.
- Messages received from the web controller published to the first WebFlux stream are received by the web client.
Next let’s look at the Back end web service.
Below is an example of how the WebFlux publisher is set up on the back end using a SseEmitter object to publish events for subscribers to consume.
I did not create a Spring service to be called by the RESTful method as it was not necessary for a WebFlux demonstration. What is important is how this simulated long-running process runs in a worker thread so the WebFlux stream can stay alive, and the SseEmitter object is returned to the caller (line 60). Each event in the process is published to the stream via the send method on line 42. Notice that caught exceptions thrown by the long-running process can be converted to error events and streamed to the caller on line 51. That’s about it. Pretty easy. Now let’s look at the web controller.
When working with the ReactJS web developer, I was told that a separate REST endpoint was needed to open the SseEmitter stream, because the SSE (Server Sent Events) standard does not support the POST method. He needed to use EventSource to open the stream with a GET request. When the stream is open, he uses the fetch method to create the POST request to the actual endpoint that calls the long running process. Below is the endpoint used to create the event stream.
The SseEmitter object is declared as a class member so it can be accessed by the pass-through method for calling the long-running process. Now let’s look at the pass-through method.
This method calls the long-running back end process then subscribes to the WebFlux stream returned by it (line 41 and 42). What is interesting here is that this method is both a subscriber to the back end stream and a publisher for the web client. The first thing to notice on line 35 is produces = MediaType.TEXT_EVENT_STREAM_VALUE that declares the media type of the response. In line 42, the response from the POST request is converted to a Flux object of type Event, which is returned to the web client (line 62). The Flux object then subscribes to the events streamed from the back end service on line 44. Upon receiving an event, the SseEmitter object publishes it for the web app to consume on line 46. Notice the back end service sends a special event to let the controller know when the long-running process has either finished or thrown an exception, so the controller can close the stream (line 48 and 52). Now let’s have a look at the web client.
As mentioned earlier, the customer was using a ReactJS web client. For the sake of time, I decided to use a simple HTML document with a bit of vanilla javascript. I am sure anyone interested in using WebFlux based on this article will likely use their own web client anyway. However it is important to note that the web developer needed to use fetch to make the POST request to the REST controller, because the web app is unable to subscribe to the event stream on the back end. This is why EventSource is used to open the stream and listen for events and fetch is used for the POST request to call the long-running process.
The example above does not make a POST request, but it does describe how to receive events streaming from the controller. This part of the tutorial is not that important. I just needed a vehicle to demonstrate everything else. There are two things to reiterate here. First, the first EventSource object (Webflux) in the web app is used to open and subscribe to the stream between the web app and the web controller. The reason is due to the fact that EventSource does not support the POST method. Secondly, the second EventSource object (source) is used to call the long-running process via the REST controller. These two webflux streams act in concert to pass messages from the back end through the web controller to the web app. Below is the web client in action via an animated gif that works as well as a video.
And of course, any feedback is appreciated. After all, this document is not just for informational purposes, but to start some collaboration among any and all interested parties.
Webflux is lightweight and easy to use with a broad spectrum of configurations to fit any need, and I hope my experience with it may be of assistance to any application developers out there looking for related solutions.
Connect with Red Hat Services
Learn more about Red Hat Consulting
Learn more about Red Hat Training
Join the Red Hat Learning Community
Learn more about Red Hat Certification
Subscribe to the Training Newsletter
Follow Red Hat Services on Twitter
Follow Red Hat Open Innovation Labs on Twitter
Like Red Hat Services on Facebook
Watch Red Hat Training videos on YouTube
Understand the value of Red Hat Certified Professionals
저자 소개
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
오리지널 쇼
엔터프라이즈 기술 분야의 제작자와 리더가 전하는 흥미로운 스토리
제품
- Red Hat Enterprise Linux
- Red Hat OpenShift Enterprise
- Red Hat Ansible Automation Platform
- 클라우드 서비스
- 모든 제품 보기
툴
체험, 구매 & 영업
커뮤니케이션
Red Hat 소개
Red Hat은 Linux, 클라우드, 컨테이너, 쿠버네티스 등을 포함한 글로벌 엔터프라이즈 오픈소스 솔루션 공급업체입니다. Red Hat은 코어 데이터센터에서 네트워크 엣지에 이르기까지 다양한 플랫폼과 환경에서 기업의 업무 편의성을 높여 주는 강화된 기능의 솔루션을 제공합니다.