Bevezetés a funkcionális webes keretrendszerbe 5. tavasszal

1. Bemutatkozás

A Spring WebFlux egy új, funkcionális webkeret, amely reaktív elvek alapján épül fel.

Ebben az oktatóanyagban megtudhatjuk, hogyan kell vele a gyakorlatban dolgozni.

Ezt alapul vesszük a Spring 5 WebFlux meglévő útmutatónkba. Ebben az útmutatóban egy egyszerű, reaktív REST alkalmazást hoztunk létre annotáció-alapú összetevők felhasználásával. Itt inkább a funkcionális keretet fogjuk használni.

2. Maven-függőség

Ugyanezre lesz szükségünk spring-boot-starter-webflux az előző cikkben meghatározott függőség:

 org.springframework.boot spring-boot-starter-webflux 2.2.6. KÖZLEMÉNY 

3. Funkcionális webes keretrendszer

A funkcionális webes keretrendszer egy új programozási modellt vezet be, ahol függvényeket használunk a kérések továbbításához és kezeléséhez.

Az annotáció-alapú modellel szemben, ahol annotáció-leképezéseket használunk, itt fogjuk használni HandlerFunction és RouterFunctions.

Hasonlóan, mint az annotált vezérlőknél, a funkcionális végpontok megközelítése ugyanarra a reaktív veremre épül.

3.1. HandlerFunction

A HandlerFunction olyan funkciót képvisel, amely válaszokat generál a hozzájuk továbbított kérésekre:

@FunctionalInterface nyilvános felület HandlerFunction {Mono fogantyú (ServerRequest kérés); }

Ez a felület elsősorban a Funkció, amely nagyon hasonlít egy servlethez.

Bár egy szabványhoz képest Servlet # szolgáltatás (ServletRequest req, ServletResponse res), HandlerFunction nem választ választ bemeneti paraméterként.

3.2. RouterFunction

RouterFunction alternatívájaként szolgál a @RequestMapping annotáció. Használhatjuk a kérelmek továbbítására a kezelő funkciókhoz:

@FunctionalInterface nyilvános felület RouterFunction {Mono útvonal (ServerRequest kérés); // ...}

Általában importálhatjuk a segítő funkciót RouterFunctions.route () útvonalak létrehozásához a teljes útválasztó funkció írása helyett.

Ez lehetővé teszi számunkra a kérelmek továbbítását a RequestPredicate. Ha az állítmány megegyezik, akkor a második argumentum, a kezelő függvény adódik vissza:

nyilvános statikus RouterFunction útvonal (RequestPredicate predikátum, HandlerFunction handlerFunction)

Mert a útvonal() metódus a RouterFunction, láncolhatjuk erőteljes és összetett útválasztási sémák kiépítésére.

4. Reaktív REST alkalmazás funkcionális web használatával

Előző útmutatónkban létrehoztunk egy egyszerű EmployeeManagement REST alkalmazás használatával @RestController és Webkliens.

Most valósítsuk meg ugyanazt a logikát az útválasztó és a kezelő funkciók használatával.

Első, útvonalakat kell létrehoznunk RouterFunction hogy közzétegyük és elfogyasszuk a reaktív folyamatainkat Munkavállalós.

Az útvonalak tavaszi babként vannak regisztrálva, és bármilyen konfigurációs osztályon belül létrehozhatók.

4.1. Egyetlen forrás

Készítsük el az első útvonalat a RouterFunction amely kislemezt jelentet meg Munkavállaló forrás:

@Bean RouterFunction getEmployeeByIdRoute () {visszatérési útvonal (GET ("/ alkalmazottak / {id}"), req -> ok (). Body (workerRepository (). FindEmployeeById (req.pathVariable ("id")), Employee.class )); }

Az első argumentum egy kérés predikátum. Figyelje meg, hogyan használtunk statikusan importált termékeket RequestPredicates.GET módszer itt. A második paraméter meghatározza a kezelő függvényt, amelyet akkor használunk, ha az állítmány érvényes.

Más szavakkal, a fenti példa átirányítja az összes GET-kérést / alkalmazottak / {id} nak nek EmployeeRepository # findEmployeeById (karakterlánc azonosító) módszer.

4.2. Gyűjtemény erőforrása

Ezután egy gyűjtemény-erőforrás közzétételéhez adjunk hozzá egy másik útvonalat:

@Bean RouterFunction getAllEmployeesRoute () {visszatérési útvonal (GET ("/ alkalmazottak"), req -> ok (). Body (workerRepository (). FindAllEmployees (), Employee.class)); }

4.3. Egyetlen forrás frissítése

Végül adjunk hozzá egy útvonalat a Munkavállaló forrás:

@Bean RouterFunction updateEmployeeRoute () {visszatérési útvonal (POST ("/ alkalmazottak / frissítés"), req -> req.body (toMono (Employee.class)). DoOnNext (workerRepository () :: updateEmployee). Akkor (ok () .épít())); }

5. Útvonalak összeállítása

Össze is állíthatjuk az útvonalakat egyetlen útválasztó funkcióban.

Nézzük meg, hogyan lehet kombinálni a fent létrehozott útvonalakat:

@Bean RouterFunction összetett útvonalak () {visszatérési útvonal (GET ("/ alkalmazottak"), req -> ok (). Body (workerRepository (). FindAllEmployees (), Employee.class)) .and (route (GET ("/ alkalmazottak) / {id} "), req -> ok (). test (workerRepository (). findEmployeeById (req.pathVariable (" id ")), Employee.class))). "), req -> req.body (toMono (Employee.class)) .doOnNext (workerRepository () :: updateEmployee) .majd (ok (). build ()))); }

Itt használtuk RouterFunction.and () hogy összekapcsoljuk az útjainkat.

Végül megvalósítottuk a teljes REST API-t, amelyre szükségünk van EmployeeManagement alkalmazás, routerek és kezelők használatával.

Az alkalmazás futtatásához használhatunk külön útvonalakat, vagy a fentiekben létrehozott egyetlen, összetett utat.

6. Útvonalak tesztelése

Tudjuk használni WebTestClient hogy teszteljük az útjainkat.

Ehhez először össze kell kötnünk az útvonalakat a bindToRouterFunction metódust, majd hozza létre a teszt kliens példányt.

Teszteljük a mi getEmployeeByIdRoute:

@Test public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee () {WebTestClient kliens = WebTestClient .bindToRouterFunction (config.getEmployeeByIdRoute ()) .build (); Alkalmazott alkalmazott = új alkalmazott ("1", "1. alkalmazott"); adott (workerRepository.findEmployeeById ("1")). willReturn (Mono.just (alkalmazott)); client.get () .uri ("/ alkalmazottak / 1") .exchange () .expectStatus () .isOk () .expectBody (Employee.class) .isEqualTo (alkalmazott); }

és hasonlóan getAllEmployeesRoute:

@Test public void whenGetAllEmployees_thenCorrectEmployees () {WebTestClient client = WebTestClient .bindToRouterFunction (config.getAllEmployeesRoute ()) .build (); Alkalmazottak listája = Arrays.asList (új alkalmazott ("1", "1. alkalmazott"), új alkalmazott ("2", "2. alkalmazott")); Flux alkalmazottFlux = Flux.fromIterable (alkalmazottak); adott (workerRepository.findAllEmployees ()). willReturn (workerFlux); client.get () .uri ("/ alkalmazottak") .exchange () .expectStatus () .isOk () .expectBodyList (Employee.class) .isEqualTo (alkalmazottak); }

Kipróbálhatjuk a mi updateEmployeeRoute azzal állítva, hogy a mi Munkavállaló a példányt a EmployeeRosory:

@Test public void whenUpdateEmployee_thenEmployeeUpdated () {WebTestClient client = WebTestClient .bindToRouterFunction (config.updateEmployeeRoute ()) .build (); Alkalmazott alkalmazott = új alkalmazott ("1", "1. alkalmazott frissítve"); client.post () .uri ("/ alkalmazottak / frissítés") .body (Mono.just (alkalmazott), Employee.class) .exchange () .expectStatus () .isOk (); ellenőrizze (workerRepository) .updateEmployee (alkalmazott); }

További részletek a WebTestClient kérjük, olvassa el a bemutatónkat a munkáról Web Ügyfél és WebTestClient.

7. Összegzés

Ebben az oktatóanyagban bemutattuk az új funkcionális web keretrendszert 5 tavasszal, és megvizsgáltuk két alapvető felületét RouterFunction és HandlerFunction. Megtanultuk azt is, hogyan lehet különféle útvonalakat létrehozni a kérelem kezeléséhez és a válasz elküldéséhez.

Ezenkívül újrateremtettük EmployeeManagement alkalmazás bevezetése a Spring 5 WebFlux útmutatóhoz a funkcionális végpontok modelljével.

Mint mindig, a teljes forráskód megtalálható a Github oldalon.


$config[zx-auto] not found$config[zx-overlay] not found