27 Temmuz 2020 Pazartesi

SpringWebFlux RouterFunctions Sınıfı - @GetMapping vs Gibi İşleri Kodlar Yaparız

Giriş
Şu satırı dahil ederiz
import static org.springframework.web.reactive.function.server.RouterFunctions;
Açıklaması şöyle. Yani functional şekilde kodlamak istersek kullanılır
RouterFunction is a functional alternative to the @RequestMapping and @Controller annotation style used in standard Spring MVC.
Açıklaması şöyle
RequestMapping and Controller annotation styles are still valid in WebFlux if you are more comfortable with the old style, RouterFunctions is just a new option for your solutions.
Eski Yöntem vs Functional Endpoints
Örnek 
Mono<ResponseEntity<...>> döndüren @GetMapping yapacağımıza
@RestController @RequestMapping("/api") public class UserController { @GetMapping("/users/{id}") public Mono<ResponseEntity<User>> getUser(@PathVariable String id) { ... } @PostMapping("/users") public Mono<ResponseEntity<User>> createUser(@RequestBody Mono<User> user) { ... } }
Mono<ServerResponse<...>> döndüren kod yazarız. Şöyle yaparız
@Configuration public class UserRouter { @Bean public RouterFunction<ServerResponse> userRoutes(UserHandler handler) { return route(GET("/api/users/{id}"), handler::getUser) .andRoute(POST("/api/users"), handler::createUser); } } @Service public class UserHandler { public Mono<ServerResponse> getUser(ServerRequest request) { ... } public Mono<ServerResponse> createUser(ServerRequest request) { ... } }
Örnek
@RestController
public class ProductController {
  @RequestMapping("/product")
  public List<Product> productListing() {
    return ps.findAll();
  }
}
Şöyle yaparız. body() metodunu bir şeyle doldururuz.
@Bean public RouterFunction<ServerResponse> productListing(ProductService ps) { return route().GET("/product", req -> ok().body(ps.findAll())) .build(); }
Açıklaması şöyle
Routes are registered as Spring beans and therefore can be created in any configuration class.
Örnek
Şöyle yaparız. body() metodunu bir şeyle doldururuz.
@Bean public WebClient webClient() { return WebClient.builder() .baseUrl("http://127.0.0.1:8000") .build(); } @Bean public RouterFunction<ServerResponse> routes(WebClient webClient) { return route(GET("/"), (ServerRequest req) -> ok() .body(webClient.get() .exchangeToFlux(resp -> resp.bodyToFlux(Object.class)),Object.class)); }
nest metodu
Açıklaması şöyle
In Spring MVC can give a context path to our application. In Spring Webflux we don’t have a configuration for that. But we can set a context-path for multiple routes. Following is how we can do that.
Şöyle yaparız. Burada /context/sample ve /context/echo isimli iki URL tanımlanıyor
import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; import static org.springframework.web.reactive.function.server.RequestPredicates.*; import static org.springframework.web.reactive.function.server.RouterFunctions.nest; import static org.springframework.web.reactive.function.server.RouterFunctions.route; @Configuration public class RouterWithContext { @Autowired private Authenticator authenticator; @Bean public RouterFunction<ServerResponse> routeWithContext(SampleHandler handler) { return nest(path("/context"), sampleRoute(handler) .and(handleRequestBodyRoute(handler))) .filter(authenticator::filterRoute); } private RouterFunction<ServerResponse> sampleRoute(SampleHandler handler) { return route(GET("/sample"), handler::handleNestedRoute); } private RouterFunction<ServerResponse> handleRequestBodyRoute(SampleHandler handler) { return route(POST("/echo") .and(contentType(MediaType.APPLICATION_JSON)), handler::handleRequestWithABody); } }
route metodu
Örnek - GET
Şöyle yaparız
@Configuration
public class ExampleRouter {
  @Bean
  public RouterFunction<ServerResponse> routeExample (ExampleHandler exampleHandler) {
    return RouterFunctions
      .route(RequestPredicates.GET("/example")
      .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), exampleHandler::hello);
  }
}
@Component
public class ExampleHandler {
  public Mono<ServerResponse> hello(ServerRequest request) {
    return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
         .body(BodyInserters.fromObject("Hello, Spring WebFlux Example!"));
  }
}
Örnek
Elimizde şöyle bir Handler kod olsun
@Component
public class ProductHandler {
  @Autowired
  private ProductService productService;

  static Mono<ServerResponse> notFound = ServerResponse.notFound().build();

  //The handler to get all the available products.
  public Mono<ServerResponse> getAllProducts(ServerRequest serverRequest) {
    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
      .body(productService.getAllProducts(), Product.class);
  }
  //The handler to create a product
  public Mono<ServerResponse> createProduct(ServerRequest serverRequest) {
    Mono<Product> productToSave = serverRequest.bodyToMono(Product.class);
    return productToSave.flatMap(product ->
      ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
        .body(productService.save(product), Product.class));
  }
  //The handler to delete a product based on the product id.
  public Mono<ServerResponse> deleteProduct(ServerRequest serverRequest) {
    String id = serverRequest.pathVariable("id");
    Mono<Void> deleteItem = productService.deleteProduct(Integer.parseInt(id));
    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
      .body(deleteItem, Void.class);
  }
  //The handler to update a product.
  public Mono<ServerResponse> updateProduct(ServerRequest serverRequest) {
    return productService.update(serverRequest.bodyToMono(Product.class))
    .flatMap(product ->
      ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
        .body(fromObject(product)))
        .switchIfEmpty(notFound);
  }
}
Şöyle yaparız
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;

@Configuration
public class ProductRouter {

  //The router configuration for the product handler.
  @Bean
  public RouterFunction<ServerResponse> productsRoute(ProductHandler productHandler){
    return RouterFunctions
      .route(GET("/products").and(accept(MediaType.APPLICATION_JSON))
        ,productHandler::getAllProducts)

      .andRoute(POST("/product").and(accept(MediaType.APPLICATION_JSON))
        ,productHandler::createProduct)

      .andRoute(DELETE("/product/{id}").and(accept(MediaType.APPLICATION_JSON))
        ,productHandler::deleteProduct)

      .andRoute(PUT("/product/{id}").and(accept(MediaType.APPLICATION_JSON))
        ,productHandler::updateProduct);
    }
}
Örnek
Şöyle yaparız
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration
public class RouterConfiguration {

  @Bean
  RouterFunction<ServerResponse> routerFunction(HelloWorldHandler helloWorldHandler) {
    return RouterFunctions.route()
      .GET("/helloworld", accept(MediaType.TEXT_PLAIN), helloWorldHandler::helloworld)
      .build();
    }
}

@Component
@RequiredArgsConstructor
public class HelloWorldHandler {

  private final HelloWorldService helloWorldService;

  public Mono<ServerResponse> helloworld(ServerRequest serverRequest) {
    return ok()
      .contentType(MediaType.TEXT_PLAIN)
      .body(BodyInserters.fromProducer(helloWorldService.helloworld(), String.class));
  }
}

@Service
public class HelloWorldService {
  public Mono<String> helloworld() {
    return Mono.just("Hello World!");
  }
}
Örnek - POST
Şöyle yaparız
@Configuration public class MyRouterConfig { @Bean public RouterFunction<ServerResponse> myRoutes() { return RouterFunctions .route(RequestPredicates.GET("/hello"), this::handleHelloRequest) .andRoute(RequestPredicates.POST("/users"), this::handleUserCreation); } private Mono<ServerResponse> handleHelloRequest(ServerRequest request) { return ServerResponse.ok().bodyValue("Hello, World!"); } private Mono<ServerResponse> handleUserCreation(ServerRequest request) { // Handle user creation logic } }

Hiç yorum yok:

Yorum Gönder