Before reading this blog, make sure to refer to my previous blog on Reactive programming
Now, let's try to understand the main difference between traditional REST and reactive programming concept. Here we are using the springwebflux as it is build on Project reactor so has all reactive specification implemented for us.
We will see both the REST and Reactive way of programming in one application only.
Please follow below steps for creating Springwebflux project. I am using Spring STS as IDE.
Click on finish button.
This will be our pom.xml
1- Pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.siddhu</groupId> <artifactId>springboot-webflux</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot-webflux</name> <description>This example shows Reactive example using springwebflux</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project> |
Now lets create few of the folder
1- Controller
2- Dao
3- Service
4- dto
create a dto class as Employee
1- Employee
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | /** * */ package com.siddhu.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * */ package com.siddhu.dto; import java.io.Serializable; /** * @author Siddhartha * */ public class Employee implements Serializable{ @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } } |
Now lets create dao class EmployeeDao
1- EmployeeDao
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package com.siddhu.dao; import java.time.Duration; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.springframework.stereotype.Component; import com.siddhu.dto.Employee; import reactor.core.publisher.Flux; @Component public class EmployeeDao { private static void sleepExecution(int i){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public List<Employee> getEmployees() { return IntStream.rangeClosed(1, 5) .peek(EmployeeDao::sleepExecution) .peek(i -> System.out.println("processing Iteration count : " + i)) .mapToObj(i -> new Employee(i, "Employee" + i)) .collect(Collectors.toList()); } public Flux<Employee> getEmployeesStream() { return Flux.range(1,5) .delayElements(Duration.ofSeconds(1)) .doOnNext(i -> System.out.println("processing Iteration count in stream flow : " + i)) .map(i -> new Employee(i, "Employee" + i)); } } |
Now create Service
1- EmployeeService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.siddhu.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.siddhu.dao.EmployeeDao; import com.siddhu.dto.Employee; import reactor.core.publisher.Flux; @Service public class EmployeeService { @Autowired private EmployeeDao dao; public List<Employee> loadAllEmployees() { long start = System.currentTimeMillis(); List<Employee> employees = dao.getEmployees(); long end = System.currentTimeMillis(); System.out.println("Total execution time : " + (end - start)); return employees; } public Flux<Employee> loadAllEmployeesStream() { long start = System.currentTimeMillis(); Flux<Employee> employees = dao.getEmployeesStream(); long end = System.currentTimeMillis(); System.out.println("Total execution time : " + (end - start)); return employees; } } |
Now create controller class
1- EmployeeController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package com.siddhu.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.siddhu.dto.Employee; import com.siddhu.service.EmployeeService; import reactor.core.publisher.Flux; @RestController @RequestMapping("/employees") public class EmployeeController { @Autowired private EmployeeService service; @GetMapping public List<Employee> getAllEmployees() { return service.loadAllEmployees(); } @GetMapping(value = "/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<Employee> getAllEmployeesStream() { return service.loadAllEmployeesStream(); } } |
Start the Springboot application
You can see the server started on Netty server.
Now execute below url and you will find following output
REST base approach:-
http://localhost:8080/employees
Now lets execute belwo url
http://localhost:8080/employees/stream
As this is Reactive behaviour we will see the output as soon as it is comming from the Microservice. It is not like that all the five record are generated on the server and then the response is send back to Client it is like as soon as the data is generated by the server/microservice you will be able to see the output
You can download the code from
https://github.com/shdhumale/springboot-webflux.git
No comments:
Post a Comment