Ръководство за Spring 5 WebFlux

1. Общ преглед

Spring WebFlux е част от Spring 5 и осигурява поддръжка на реактивно програмиране за уеб приложения.

В този урок ще създадем малко реактивно приложение REST, използващо реактивните уеб компоненти RestController и WebClient.

Също така ще разгледаме как да защитим нашите реактивни крайни точки, използвайки Spring Security.

2. Spring WebFlux Framework

Spring WebFlux използва вътрешно Project Reactor и неговите издателски реализации - Flux и Mono .

Новата рамка поддържа два модела за програмиране:

  • Реактивни компоненти на базата на анотации
  • Функционално маршрутизиране и обработка

Ще се съсредоточим върху базирани на анотации реактивни компоненти, тъй като вече изследвахме функционалния стил - маршрутизиране и обработка в друг урок.

3. Зависимости

Нека започнем с зависимостта spring-boot-starter-webflux , която включва всички останали необходими зависимости:

  • spring-boot и spring-boot-starter за основна настройка на приложението Spring Boot
  • spring-webflux рамка
  • реакторно ядро, което ни е необходимо за реактивни потоци, а също и реакторна мрежа
 org.springframework.boot spring-boot-starter-webflux 2.2.6.RELEASE 

Най-новата пролет-boot-starter-webflux може да бъде изтеглена от Maven Central.

4. Реактивно приложение REST

Сега ще изградим много просто реактивно приложение REST EmployeeManagement - използвайки Spring WebFlux:

  • Ще използваме прост модел на домейн - Служител с поле за идентификация и име
  • Ще изградим REST API с RestController, за да публикуваме ресурси на служителите като отделен ресурс и като колекция
  • Ще изградим клиент с WebClient, за да извлечем същия ресурс
  • Ще създадем защитена реактивна крайна точка, използвайки WebFlux и Spring Security

5. Reactive RestController

Spring WebFlux поддържа конфигурации, базирани на анотации, по същия начин като Spring Web MVC framework.

Като начало на сървъра създаваме коментиран контролер, който публикува реактивен поток от ресурса Служител .

Нека създадем нашия анотиран EmployeeController :

@RestController @RequestMapping("/employees") public class EmployeeController { private final EmployeeRepository employeeRepository; // constructor... }

СлужителятRepository може да бъде всяко хранилище на данни, което поддържа неблокиращи реактивни потоци.

5.1. Единичен ресурс

Нека създадем крайна точка в нашия контролер, която публикува един ресурс за служители :

@GetMapping("/{id}") private Mono getEmployeeById(@PathVariable String id) { return employeeRepository.findEmployeeById(id); }

Ние обвиваме един ресурс на служител в моно, защото връщаме най-много един служител.

5.2. Ресурс за събиране

Нека добавим и крайна точка, която публикува ресурса за събиране на всички служители :

@GetMapping private Flux getAllEmployees() { return employeeRepository.findAllEmployees(); }

За ресурса за събиране използваме поток от тип Служител - тъй като това е издателят за 0. .n елементи.

6. Реактивен уеб клиент

WebClient, представен през Spring 5, е неблокиращ клиент с поддръжка за реактивни потоци.

Можем да използваме WebClient, за да създадем клиент за извличане на данни от крайните точки, предоставени от EmployeeController.

Нека създадем прост EmployeeWebClient :

public class EmployeeWebClient { WebClient client = WebClient.create("//localhost:8080"); // ... }

Тук създадохме WebClient, използвайки неговия фабричен метод create . Той ще сочи към localhost: 8080, за да можем да използваме или относителни URL адреси за обаждания, направени от този клиентски екземпляр.

6.1. Извличане на един ресурс

За да извлечете единичен ресурс от типа Mono от крайна точка / служител / {id} :

Mono employeeMono = client.get() .uri("/employees/{id}", "1") .retrieve() .bodyToMono(Employee.class); employeeMono.subscribe(System.out::println);

6.2. Извличане на ресурс за събиране

По същия начин, за да извлечете ресурс за събиране от тип Flux от крайна точка / служители :

Flux employeeFlux = client.get() .uri("/employees") .retrieve() .bodyToFlux(Employee.class); employeeFlux.subscribe(System.out::println);

Имаме и подробна статия за настройка и работа с WebClient .

7. Spring WebFlux Security

Можем да използваме Spring Security, за да защитим нашите реактивни крайни точки.

Да предположим, че имаме нова крайна точка в нашия EmployeeController. Тази крайна точка актуализира данните за служителя и изпраща обратно актуализирания служител.

Тъй като това позволява на потребителите да променят съществуващите служители, ние искаме да ограничим тази крайна точка само до потребители на ADMIN роля.

Нека добавим нов метод към нашия EmployeeController :

@PostMapping("/update") private Mono updateEmployee(@RequestBody Employee employee) { return employeeRepository.updateEmployee(employee); }

Now, to restrict access to this method let's create SecurityConfig and define some path-based rules to only allow ADMIN users:

@EnableWebFluxSecurity public class EmployeeWebSecurityConfig { // ... @Bean public SecurityWebFilterChain springSecurityFilterChain( ServerHttpSecurity http) { http.csrf().disable() .authorizeExchange() .pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN") .pathMatchers("/**").permitAll() .and() .httpBasic(); return http.build(); } }

This configuration will restrict access to the endpoint /employees/update. Therefore only users having a role ADMIN will be able to access this endpoint and update an existing Employee.

Finally, the annotation @EnableWebFluxSecurity adds Spring Security WebFlux support with some default configurations.

We also have a detailed article on configuring and working with Spring WebFlux security.

8. Conclusion

In this article, we've explored how to create and work with reactive web components as supported by the Spring WebFlux framework. As an example, we've built a small Reactive REST application.

We learned how to use RestController and WebClient to publish and consume reactive streams.

We also looked into how to create a secured reactive endpoint with the help of Spring Security.

Other than Reactive RestController and WebClient, the WebFlux framework also supports reactive WebSocket and the corresponding WebSocketClient for socket style streaming of Reactive Streams.

We have a detailed article focused on working with Reactive WebSocket with Spring 5.

И накрая, пълният изходен код, използван в този урок, е наличен в Github.