Functional Programming với Spring WebFlux

Spring framework version 5 với support từ Java 8 trở lên giúp chúng ta có thể sử dụng Functional Programming trong Java code. Và Spring WebFlux cũng không ngoại lệ, chúng ta cũng có thể xây dựng các ứng dụng Reactive web sử dụng Lambda Expression. Trong bài viết này, mình sẽ hướng dẫn các bạn làm thế nào để sử dụng Functional Programming với Spring WebFlux các bạn nhé!

Đầu tiên, mình cũng sẽ tạo mới Spring Boot project với Reactive Web support sử dụng Spring Initializr Web để làm ví dụ:

Functional Programming với Spring WebFlux

Nếu bạn nào chưa biết cách tạo Spring Boot project với Spring Initializr Web thì có thể tham khảo bài viết này nhé.

Lưu ý là sau khi tạo project xong, các bạn hãy mở tập tin Maven pom.xml và remove dependency spring-boot-starter-web đi:

Nếu không thì chúng ta sẽ không chạy ví dụ được!

Tương tự như trong bài viết về Spring WebFlux sử dụng annotation, trong bài viết này, mình cũng sẽ tạo một ứng dụng cung cấp danh sách sinh viên với dữ liệu được thêm vào sau mỗi một giây. Khi người dùng request tới ứng dụng của chúng ta thì mỗi khi một sinh viên mới được thêm vào, thông tin của sinh viên này sẽ được publish tới cho người dùng. 

Thông tin sinh viên sẽ chứa trong đối tượng Student như sau:

Ở đây, mình cũng đã sử dụng Project Lombok.

Với Functional Programming trong Spring WebFlux, thay vì chúng ta sử dụng các annotation trong Spring MVC, bây giờ chúng ta sẽ sử dụng đối tượng HandlerFunction với Lambda Expression để xử lý request và map request URL tới đối tượng HandlerFunction sử dụng đối tượng RouterFunction.

Ở đây, chúng ta có thể xem RouterFunction giống như annotation @RequestMapping dùng để định nghĩa request URL, HTTP method, … và HandlerFunction là phương thức được khai báo với annotation @RequestMapping trong Spring MVC.

  • HandlerFunction là một Functional Interface sẽ process request từ người dùng từ đối tượng ServerRequest và trả về client đối tượng ServerResponse.

Nội dung của interface này như sau:

Ở đây, các đối tượng ServerRequest và ServerResponse là những đối tượng mới được giới thiệu cùng với Spring WebFlux để nắm giữ các thông tin về request và response của một request URL trong các ứng dụng Reactive web. Chúng ta có thể lấy được các đối tượng Mono hay Flux trong Project Reactor từ các đối tượng này.

Trong ví dụ của bài viết này, mình sẽ tạo một đối tượng HandlerFunction với nội dung như sau:

Phương thức ServerResponse.ok() nghĩa là chúng ta sẽ return lại kết quả cho client với HTTP status code là 200. Ở đây, mình cũng sử dụng Content-Type là “text/event-stream” để mỗi khi có dữ liệu mới thì server sẽ cập nhập dữ liệu đó cho client.

Phương thức body() định nghĩa data sẽ trả về cho client. Trong phương thức này, mình cũng định nghĩa phương thức all() để tạo mới thông tin sinh viên sau thời gian một giây như sau:

Với đối tượng RandomStringGenerator được sử dụng từ thư viện Apache Commons Text:

  • RouterFunction cũng là một Functional Interface và nó sẽ map request URL tới một HandlerFunction sử dụng đối tượng RequestPredicate để xử lý request từ người dùng.

Nội dung của interface RouterFunction như sau:

Chúng ta có thể sử dụng các phương thức static của đối tượng RequestPredicates để tạo đối tượng RequestPredicate:

và các phương thức static của đối tượng RouterFunctions để tạo đối tượng RouterFunction từ đối tượng RequestPredicate và HandlerFunction ở trên:

Toàn bộ code để tạo request URL như sau:

Nếu sử dụng Lambda Expression, code chúng ta có thể viết gọn lại như sau:

  • Để đăng ký request URL này với Spring WebFux, chúng ta cần khai báo RouterFunction trong Spring container.

Để đơn giản, mình sẽ khai báo bean cho đối tượng RouterFunction ngay trong tập tin SpringWebfluxFunctionalApplication luôn. Nội dung của tập tin này lúc này sẽ như sau:

Vậy là xong rồi đó các bạn, thử chạy xem nào!

Các bạn cũng sẽ thấy cứ sau một giây, một sinh viên mới được thêm vào và trả về cho người dùng như sau:

Functional Programming với Spring WebFlux


Add Comment