Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reactive Card Magic: Understanding Spring WebFlux and Project Reactor

422 views

Published on

Spring Framework 5.0 and Spring Boot 2.0 contain groundbreaking technologies known as reactive streams, which enable applications to utilize computing resources efficiently.

In this session, James Weaver will discuss the reactive capabilities of Spring, including WebFlux, WebClient, Project Reactor, and functional reactive programming. The session will be centered around a fun demonstration application that illustrates reactive operations in the context of manipulating playing cards.

Presenter : James Weaver, Pivotal

Published in: Technology

Reactive Card Magic: Understanding Spring WebFlux and Project Reactor

  1. 1. Reactive Card Magic @JavaFXpert Web on Reactive Stack with Spring
  2. 2. About Presenter James Weaver @JavaFXpert Developer Advocate and International Speaker for Pivotal
  3. 3. @JavaFXpert
  4. 4. @JavaFXpert
  5. 5. Reactive Card Magic What will we cover? • Spring WebFlux (what, why, etc.) • Reactive systems and Reactive programming • Reactive programming in Java • Project Reactor • WebClient reactive client • Code and concepts walkthrough of Reactive Card Magic application @JavaFXpert
  6. 6. Spring WebFlux What is it? @JavaFXpert A non-blocking, reactive web framework that supports Reactive Streams back pressure, and runs on servers such as Netty, Undertow, and Servlet 3.1+ containers. See: Web on Reactive Stack by the Spring team
  7. 7. WebFlux Like WebMVC but Reactive @JavaFXpert
  8. 8. Spring WebFlux Why was it created? • Because of mobile devices, IoT, and our continuing trend to live online, some apps today have millions of clients. • Many apps have Black Friday* style usage patterns, where demand can spike exponentially. • Factors such as these drive the need for a non-blocking web stack that: • handles concurrency with a small number of threads and • scales with less hardware resources. @JavaFXpert * Referring to the busiest shopping day of the year in the US, not the last Friday before Christmas in the UK :-)
  9. 9. @JavaFXpert
  10. 10. @JavaFXpert
  11. 11. @JavaFXpert
  12. 12. Spring WebFlux Other reasons for creating it • Continuation style APIs enabled by Java 8 lambda expressions allow declarative composition of asynchronous logic • Lambdas also enabled Spring WebFlux to offer functional web endpoints alongside with annotated controllers @JavaFXpert
  13. 13. Spring WebFlux What does reactive mean? • Reactive refers to programming models (and systems) that are built around asynchronously reacting to external changes (such as messages and events) • An important mechanism in reactive is non-blocking back pressure (flow control) * @JavaFXpert See: Web on Reactive Stack by the Spring team * In synchronous, imperative code, blocking calls serve as a natural form of back pressure that forces the caller to wait.
  14. 14. reactivemanifesto.org The Reactive Manifesto @JavaFXpert
  15. 15. Reactive systems vs. Reactive programming • Reactive systems represent an architectural style that allows multiple individual applications to coalesce as a single unit, reacting to its surroundings, while remaining aware of each other • Reactive programming is a subset of asynchronous programming and a paradigm where the availability of new information drives the logic forward rather than having control flow driven by a thread-of-execution @JavaFXpert From Reactive programming vs. Reactive systems by Jonas Bonér and Viktor Klang
  16. 16. Some Reactive programming use cases • External Service Calls • Highly Concurrent Message Consumers • Spreadsheets • Abstraction Over (A)synchronous Processing @JavaFXpert From: Notes on Reactive Programming Part I: The Reactive Landscape by Dave Syer
  17. 17. Reactive Programming in Java A brief and incomplete history • Reactive programming ideas have been around for a while, appearing in programming languages (e.g. Erlang) and libraries (e.g. Reactive Extensions for .NET) • The open source RxJava (Reactive Extensions for Java) project helped move reactive programming forward on the Java platform. • The Reactive Streams initiative provided a standard and specification for compatibility among reactive implementations in Java. This initiative is a collaboration between engineers from Kaazing, Lightbend, Netflix, Pivotal, Red Hat, Twitter and others. @JavaFXpert
  18. 18. Reactive Programming in Java • Reactive Streams • RxJava • Reactor • Spring Framework 5 • Ratpack • Akka • Vert.x @JavaFXpert From: Notes on Reactive Programming Part I: The Reactive Landscape by Dave Syer
  19. 19. Reactive Streams: @JavaFXpert github.com/reactive-streams/reactive-streams-jvm Is a standard and specification for stream-oriented libraries that: • process a potentially unbounded number of elements • sequentially, • with the ability to asynchronously pass elements between components, • with mandatory non-blocking backpressure. reactive-streams.org
  20. 20. public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); } Reactive Streams API for Java @JavaFXpert enables interoperability between different Reactive implementations public interface Publisher<T> { public void subscribe(Subscriber<? super T> s); } public interface Subscription { public void request(long n); public void cancel(); } public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { } Adopted by Java 9 in the Flow class
  21. 21. Reactive Streams with Spring @JavaFXpert From: Servlet and Reactive Stacks in Spring Framework 5 by Rossen Stoyanchev Streaming to database with non-blocking back pressure JSON stream
  22. 22. Reactive Streams with Spring @JavaFXpert From: Servlet and Reactive Stacks in Spring Framework 5 by Rossen Stoyanchev Streaming from database with non-blocking back pressure JSON stream
  23. 23. 23 Project Reactor The reactive library of choice for Spring WebFlux
  24. 24. Project Reactor Avoiding callback hell and other asynchronous pitfalls Reactive libraries such as Reactor aim to address drawbacks of "classic" asynchronous approaches on the JVM while also focusing on additional aspects: • Composability and readability • Data as a flow manipulated with a rich vocabulary of operators • Nothing happens until you subscribe • Backpressure or the ability for the consumer to signal the producer that the rate of emission is too high • High level but high value abstraction that is concurrency-agnostic @JavaFXpertSee: From Imperative to Reactive Programming in Project Reactor Guide
  25. 25. abstract class Flux<T> implements Publisher<T> { ... } abstract class Flux<T> implements Publisher<T> { ... } Reactive Types
  26. 26. abstract class Mono<T> implements Publisher<T> { ... } abstract class Mono<T> implements Publisher<T> { ... } Reactive Types
  27. 27. Reactive Types •Mono<T>
  28. 28. Reactive Types •Mono<T> •Flux<T>
  29. 29. Flux.just("Hello", "Reactor", "World") .subscribe(s -> System.out.println(s)); @JavaFXpert Hello Reactor World Project Reactor Simple example
  30. 30. Project Reactor Marble diagram: Mono @JavaFXpert
  31. 31. Project Reactor Marble diagram: Flux @JavaFXpert
  32. 32. Marble diagrams 32
  33. 33. 12:51 13:00
  34. 34. Flip
  35. 35. Flip
  36. 36. Reactive Marbles rxmarbles.com 37
  37. 37. App we’ll use for code examples @JavaFXpert
  38. 38. @JavaFXpert CardDeck Repository Hand Frequency Respository Card Deck Service Card Shuffling Service Proxy Poker Service Card Deck Controller Poker Controller Poker Service Card Deck Data Loader WebClient Mono<CardHand> Flux<HandFrequency> Flux<Card>Mono<String> Flux<HandFrequency> Flux<Card>Flux<Card> Reactive Card Magic Application Architecture
  39. 39. Getting a New Deck @JavaFXpert
  40. 40. @RestController @RequestMapping("/cards/deck") public class CardDeckController { private final CardDeckService cardDeckService; @Autowired public CardDeckController( CardDeckService cardDeckService) { this.cardDeckService = cardDeckService; } @GetMapping("/new") public Mono<CardHand> getCardDeck(@RequestParam(defaultValue = "52") int numcards) { return cardDeckService.generate() .take(numcards) .collectList() .map(l -> new CardHand(l, "New Deck")); } } @JavaFXpert Annotated controller example
  41. 41. @RestController @RequestMapping("/cards/deck") public class CardDeckController { private final CardDeckService cardDeckService; @Autowired public CardDeckController( CardDeckService cardDeckService) { this.cardDeckService = cardDeckService; } @GetMapping("/new") public Mono<CardHand> getCardDeck(@RequestParam(defaultValue = "52") int numcards) { return cardDeckService.generate() .take(numcards) .collectList() .map(l -> new CardHand(l, "New Deck")); } } Annotated controller example @JavaFXpert
  42. 42. @Bean RouterFunction<ServerResponse> newDeckRoutes(CardDeckService cds) { int defaultNumCards = 52; return RouterFunctions.route( RequestPredicates.GET("/newdeck"), request -> cds.generate() .take(request.queryParam("numcards") .map(Integer::parseInt).orElse(defaultNumCards)) .collectList() .map(l -> new CardHand(l,"New Deck")) .flatMap(ServerResponse.ok()::syncBody)); } Functional endpoint example @JavaFXpert
  43. 43. Spring WebFlux Using WebClient WebClient is a reactive, non-blocking client for HTTP requests with a functional-style API client and Reactive Streams support. By comparison to the RestTemplate, WebClient is: • non-blocking, reactive, and supports higher concurrency with less hardware resources. • provides a functional API that takes advantage of Java 8 lambdas. • supports both synchronous and asynchronous scenarios. • supports streaming up or down from a server. @JavaFXpertFrom Web on Reactive Stack - WebClient
  44. 44. Identifying a Poker hand @JavaFXpert
  45. 45. WebClient pokerWebClient = WebClient.create("http://127.0.0.1:8080"); Mono<String> pokerHandMono = pokerWebClient.post() .uri("/poker/idhand") .body(cardFlux, Card.class) .retrieve() .bodyToMono(String.class); WebClient example @JavaFXpert Calling an endpoint to identify a Poker hand
  46. 46. Using Reactor operators examples from the Reactive Card Magic application @JavaFXpert Mono defaultIfEmpty() flatMap() flatMapMany() map() retryWhen() then() timeout() Flux as() flatMapIterable() sort() collectList() fromArray() subscribe() compose() fromStream() subscribeOn() concatWith() index() take() defer() just() transform() distinct() map() zip() filter() range() flatMap() skip()
  47. 47. Dealing ten cards of same suit @JavaFXpert
  48. 48. @GetMapping("/{suit}") public Mono<CardHand> getCardDeckBySuit( @PathVariable String suit, @RequestParam(defaultValue = "10") int numcards ) { return cardDeckService.generate() .filter(card -> card.getSuit() .equalsIgnoreCase(suit)) .take(numcards) .collectList() .map(l -> new CardHand(l, "Only " + suit)); } @JavaFXpert Dealing ten cards of same suit Examining filter(), take(), collectList() and map() operators
  49. 49. @GetMapping("/{suit}") public Mono<CardHand> getCardDeckBySuit( @PathVariable String suit, @RequestParam(defaultValue = "10") int numcards ) { return cardDeckService.generate() .filter(card -> card.getSuit() .equalsIgnoreCase(suit)) .take(numcards) .collectList() .map(l -> new CardHand(l, "Only " + suit)); } @JavaFXpert Dealing ten cards of same suit Examining filter(), take(), collectList() and map() operators
  50. 50. Flux filter operator public final Flux<T> filter(Predicate<? super T> p) @JavaFXpert API documentation
  51. 51. Flux take operator public final Flux<T> take(long n) @JavaFXpert API documentation
  52. 52. Flux collectList operator public final Mono<List<T>> collectList() @JavaFXpert API documentation
  53. 53. Mono map operator public final <R> Mono<R> map(Function<? super T,? extends R> mapper) @JavaFXpert API documentation
  54. 54. Flux<Card> filter( card -> ) take( 10 ) Flux<Card> Flux<Card> collectList() Mono<List<Card>> map( list -> new CardHand(list, “Only s“)) Mono<CardHand> Only Hearts take( 9 )take( 8 )take( 7 )take( 6 )take( 5 )take( 4 )take( 3 )take( 2 )take( 1 )take( 0 )
  55. 55. Deal Poker hand: Alternating @JavaFXpert
  56. 56. private static final Comparator<Card> worthComparator = Comparator.comparingInt(Card::getWorth); public Flux<Card> dealPokerHand(Flux<Card> cardFlux) { return cardFlux.index() .take(9) .filter(t -> t.getT1() % 2 == 0) .map(Tuple2::getT2) // (t -> t.getT2()) .sort(worthComparator); } @JavaFXpert Examining index() and sort() operators Deal Poker hand: Alternating
  57. 57. Flux index operator public final Flux<Tuple2<Long,T>> index() @JavaFXpertAPI documentation
  58. 58. Flux index operator and Tuple2 Flux<Tuple2<Long,Card>> @JavaFXpertTuple2 API documentation 1 0 2 3 index value
  59. 59. Flux sort operator public final Flux<T> sort(Comparator<? super T> sortFunction) @JavaFXpertAPI documentation
  60. 60. take( 9 )take( 8 )take( 7 )take( 6 )take( 5 )take( 4 )take( 3 )take( 2 )take( 1 )take( 0 ) Flux<Card> index() Flux<Tuple2<Long,Card>> filter( t -> t.getT1() % 2 == 0 ) map( Tuple2::getT2 ) 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8Flux<Tuple2<Long,Card>> Flux<Tuple2<Long,Card>> 0 2 4 6 8 Flux<Card> Flux<Card> sort(worthComparator) 0 take( 9 )
  61. 61. Reactive Card Magic If we have time, walk through more code including: • Additional shuffling operations such as Riffle Shuffle • Populating the Card Deck repository • The /shuffledealrepeat endpoint • The /handfrequencies endpoint • Testing with StepVerifier @JavaFXpert
  62. 62. Spring WebFlux Spring MVC and/or WebFlux? @JavaFXpertFrom Web on Reactive Stack - Applicability
  63. 63. Reactive Card Magic What have we covered? Any more questions? • Spring WebFlux (what, why, etc.) • Reactive systems and Reactive programming • Reactive programming in Java • Project Reactor • WebClient reactive client • Code and concepts walkthrough of Reactive Card Magic application @JavaFXpert
  64. 64. Web resources • Spring Framework 5 Web on Reactive Stack:
 docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux • Project Reactor:
 projectreactor.io • The Reactive Manifesto:
 reactivemanifesto.org • Reactive Card Magic app:
 github.com/JavaFXpert/card-deck-demo • James Weaver’s blogs: • JavaFXpert.com • CulturedEar.com @JavaFXpert
  65. 65. Reactive Card Magic @JavaFXpert Web on Reactive Stack with Spring

×