├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── javatechie │ │ └── webflux │ │ ├── SpringbootWebfluxDemoApplication.java │ │ ├── controller │ │ └── CustomerController.java │ │ ├── dao │ │ └── CustomerDao.java │ │ ├── dto │ │ └── Customer.java │ │ ├── handler │ │ ├── CustomerHandler.java │ │ └── CustomerStreamHandler.java │ │ ├── router │ │ └── RouterConfig.java │ │ └── service │ │ └── CustomerService.java └── resources │ └── application.properties └── test └── java └── com └── javatechie └── webflux ├── MonoFluxTest.java └── SpringbootWebfluxDemoApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # springboot-webflow-demo 2 | 3 | ### Workflow : 4 | 5 | ![reactive-flow](https://user-images.githubusercontent.com/25712816/113294351-7f577880-9314-11eb-859e-23504ccdebaf.PNG) 6 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.4.4 9 | 10 | 11 | com.javatechie 12 | springboot-webflux-demo 13 | 0.0.1-SNAPSHOT 14 | springboot-webflux-demo 15 | Demo project for Spring Boot 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-webflux 23 | 24 | 25 | org.projectlombok 26 | lombok 27 | true 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-test 32 | test 33 | 34 | 35 | io.projectreactor 36 | reactor-test 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-maven-plugin 46 | 47 | 48 | 49 | org.projectlombok 50 | lombok 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/SpringbootWebfluxDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | @SpringBootApplication 10 | public class SpringbootWebfluxDemoApplication { 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(SpringbootWebfluxDemoApplication.class, args); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/controller/CustomerController.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.controller; 2 | 3 | import com.javatechie.webflux.dto.Customer; 4 | import com.javatechie.webflux.service.CustomerService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | import reactor.core.publisher.Flux; 11 | 12 | import java.util.List; 13 | 14 | @RestController 15 | @RequestMapping("/customers") 16 | public class CustomerController { 17 | @Autowired 18 | private CustomerService service; 19 | 20 | 21 | @GetMapping 22 | public List getAllCustomers() { 23 | return service.loadAllCustomers(); 24 | } 25 | 26 | @GetMapping(value = "/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE) 27 | public Flux getAllCustomersStream() { 28 | return service.loadAllCustomersStream(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/dao/CustomerDao.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.dao; 2 | 3 | import com.javatechie.webflux.dto.Customer; 4 | import org.springframework.stereotype.Component; 5 | import reactor.core.publisher.Flux; 6 | 7 | import java.time.Duration; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.IntStream; 11 | 12 | @Component 13 | public class CustomerDao { 14 | 15 | 16 | private static void sleepExecution(int i){ 17 | try { 18 | Thread.sleep(1000); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | 24 | public List getCustomers() { 25 | return IntStream.rangeClosed(1, 10) 26 | .peek(CustomerDao::sleepExecution) 27 | .peek(i -> System.out.println("processing count : " + i)) 28 | .mapToObj(i -> new Customer(i, "customer" + i)) 29 | .collect(Collectors.toList()); 30 | } 31 | 32 | 33 | public Flux getCustomersStream() { 34 | return Flux.range(1,10) 35 | .delayElements(Duration.ofSeconds(1)) 36 | .doOnNext(i -> System.out.println("processing count in stream flow : " + i)) 37 | .map(i -> new Customer(i, "customer" + i)); 38 | } 39 | 40 | 41 | public Flux getCustomerList() { 42 | return Flux.range(1,50) 43 | .doOnNext(i -> System.out.println("processing count in stream flow : " + i)) 44 | .map(i -> new Customer(i, "customer" + i)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/dto/Customer.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class Customer { 11 | 12 | private int id; 13 | private String name; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/handler/CustomerHandler.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.handler; 2 | 3 | import com.javatechie.webflux.dao.CustomerDao; 4 | import com.javatechie.webflux.dto.Customer; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.web.reactive.function.server.ServerRequest; 8 | import org.springframework.web.reactive.function.server.ServerResponse; 9 | import reactor.core.publisher.Flux; 10 | import reactor.core.publisher.Mono; 11 | 12 | @Service 13 | public class CustomerHandler { 14 | 15 | @Autowired 16 | private CustomerDao dao; 17 | 18 | 19 | public Mono loadCustomers(ServerRequest request){ 20 | Flux customerList = dao.getCustomerList(); 21 | return ServerResponse.ok().body(customerList,Customer.class); 22 | } 23 | 24 | 25 | public Mono findCustomer(ServerRequest request){ 26 | int customerId= Integer.valueOf( request.pathVariable("input")); 27 | // dao.getCustomerList().filter(c->c.getId()==customerId).take(1).single(); 28 | Mono customerMono = dao.getCustomerList().filter(c -> c.getId() == customerId).next(); 29 | return ServerResponse.ok().body(customerMono,Customer.class); 30 | } 31 | 32 | 33 | public Mono saveCustomer(ServerRequest request){ 34 | Mono customerMono = request.bodyToMono(Customer.class); 35 | Mono saveResponse = customerMono.map(dto -> dto.getId() + ":" + dto.getName()); 36 | return ServerResponse.ok().body(saveResponse,String.class); 37 | } 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/handler/CustomerStreamHandler.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.handler; 2 | 3 | import com.javatechie.webflux.dao.CustomerDao; 4 | import com.javatechie.webflux.dto.Customer; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.reactive.function.server.ServerRequest; 9 | import org.springframework.web.reactive.function.server.ServerResponse; 10 | import reactor.core.publisher.Flux; 11 | import reactor.core.publisher.Mono; 12 | 13 | @Service 14 | public class CustomerStreamHandler { 15 | 16 | @Autowired 17 | private CustomerDao dao; 18 | 19 | 20 | public Mono getCustomers(ServerRequest request) { 21 | Flux customersStream = dao.getCustomersStream(); 22 | return ServerResponse.ok(). 23 | contentType(MediaType.TEXT_EVENT_STREAM) 24 | .body(customersStream, Customer.class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/router/RouterConfig.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.router; 2 | 3 | import com.javatechie.webflux.handler.CustomerHandler; 4 | import com.javatechie.webflux.handler.CustomerStreamHandler; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.reactive.function.server.RouterFunction; 9 | import org.springframework.web.reactive.function.server.RouterFunctions; 10 | import org.springframework.web.reactive.function.server.ServerResponse; 11 | 12 | @Configuration 13 | public class RouterConfig { 14 | 15 | @Autowired 16 | private CustomerHandler handler; 17 | 18 | @Autowired 19 | private CustomerStreamHandler streamHandler; 20 | 21 | @Bean 22 | public RouterFunction routerFunction(){ 23 | return RouterFunctions.route() 24 | .GET("/router/customers",handler::loadCustomers) 25 | .GET("/router/customers/stream",streamHandler::getCustomers) 26 | .GET("/router/customer/{input}",handler::findCustomer) 27 | .POST("/router/customer/save",handler::saveCustomer) 28 | .build(); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/webflux/service/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux.service; 2 | 3 | import com.javatechie.webflux.dao.CustomerDao; 4 | import com.javatechie.webflux.dto.Customer; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import reactor.core.publisher.Flux; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class CustomerService { 13 | 14 | @Autowired 15 | private CustomerDao dao; 16 | 17 | 18 | public List loadAllCustomers() { 19 | long start = System.currentTimeMillis(); 20 | List customers = dao.getCustomers(); 21 | long end = System.currentTimeMillis(); 22 | System.out.println("Total execution time : " + (end - start)); 23 | return customers; 24 | } 25 | 26 | 27 | 28 | public Flux loadAllCustomersStream() { 29 | long start = System.currentTimeMillis(); 30 | Flux customers = dao.getCustomersStream(); 31 | long end = System.currentTimeMillis(); 32 | System.out.println("Total execution time : " + (end - start)); 33 | return customers; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9191 2 | -------------------------------------------------------------------------------- /src/test/java/com/javatechie/webflux/MonoFluxTest.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import reactor.core.publisher.Flux; 5 | import reactor.core.publisher.Mono; 6 | 7 | public class MonoFluxTest { 8 | 9 | 10 | @Test 11 | public void testMono(){ 12 | Mono monoString = Mono.just("javatechie") 13 | .then(Mono.error(new RuntimeException("Exception occured"))) 14 | .log(); 15 | monoString.subscribe(System.out::println,(e)->System.out.println(e.getMessage())); 16 | } 17 | 18 | @Test 19 | public void testFlux(){ 20 | Flux fluxString = Flux.just("Spring", "Spring Boot", "Hibernate", "microservice") 21 | .concatWithValues("AWS") 22 | .concatWith(Flux.error(new RuntimeException("Exception occured in Flux"))) 23 | .concatWithValues("cloud") 24 | .log(); 25 | 26 | fluxString.subscribe(System.out::println,(e)->System.out.println(e.getMessage())); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/javatechie/webflux/SpringbootWebfluxDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.webflux; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootWebfluxDemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------