Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Going Reactive (@technologieplauscherl)

Going Reactive (@technologieplauscherl)

Going reactive with Project Reactor, Spring 5 and Spring Data.

Christoph Strobl

July 18, 2017
Tweet

More Decks by Christoph Strobl

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Christoph Strobl
 Pivotal Software Inc.
 @stroblchristoph Going Reactive
  2. The next 30 Minutes (or so…) 2 Unless otherwise indicated,

    these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ - Where are we today - Reactor, Spring Data, Spring 5 - Some Code
  3. Synchronous Data Access 3 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ {…}
  4. Synchronous Data Access - Batching 4 Unless otherwise indicated, these

    slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ {…} Batching
  5. Asynchronous Data Access 5 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ {…} Dispatcher Thread: Worker A Thread: Worker B Thread: Worker C
  6. Reactive Data Access 6 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ {…} Subscriber Publisher Stream
  7. 7 Unless otherwise indicated, these slides are © 2013-2017 Pivotal

    Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Iterator.next() Future.get() Subscriber.onNext(t)
  8. Reactor & Reactive Streams 8 Unless otherwise indicated, these slides

    are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Publisher<T> (0…n) Flux<T> (0…n) Mono<T> (0…1) Reactive Streams
  9. Flux 9 Unless otherwise indicated, these slides are © 2013-2017

    Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ [fluhks] - a flowing or flow Flux.just("red", "white", "blue") .flatMap(v !-> Mono.fromCallable(blockingStuff(v)) .subscribeOn(Schedulers.elastic())) .collect(Result!::new, Result!::add) .doOnNext(Result!::stop) .subscribe(doWithResult);
  10. Mono 10 Unless otherwise indicated, these slides are © 2013-2017

    Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ [mon-oh] - alone, single, one Mono.fromCallable(blockingStuff()) .map(v !-> unwarp(v)) .subscribe();
  11. Reactive with Spring 11 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring Framework
 5 Project Reactor
 3 Spring Data
 Kay
  12. Reactive Template (MongoDB) 12 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ /**
 * Query for a {@link Flux} of objects of type T from the specified collection.
 *
 * @param entityClass the parametrized type of the returned {@link Flux}.
 * @param collectionName name of the collection to retrieve the objects from
 * @return the converted collection
 */
 <T> Flux<T> findAll(Class<T> entityClass, String collectionName); /**
 * Map the results of an ad-hoc query on the collection for the entity class to a 
 * single instance of an object of the
 * specified type. 
 * @param query the query class that specifies the criteria 
 * @param entityClass the parametrized type of the returned {@link Mono}.
 * @return the converted object
 */
 <T> Mono<T> findOne(Query query, Class<T> entityClass);
  13. Spring Data Reactive 13 Unless otherwise indicated, these slides are

    © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface Repo extends ReactiveCrudRepository<Person, String> { } Flux<Person> findAllByLastname(String lastname); Flux<Person> findAllByLastname(Mono<String> lastname); Flux<Person> customQuery(String lastname); @Query("{lastname : ?0}"); Flux<Person> findAllByLastname(String ln, Pageable page);
  14. Unless otherwise indicated, these slides are © 2013-2017 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ It’s Demo Time https://github.com/christophstrobl/spring-data-reactive-demo/tree/springIO_2017
  15. Spring Data Reactive - Repository 15 Unless otherwise indicated, these

    slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { } Flux.interval(Duration.ofSeconds(1))
 .zipWith(starks)
 .map(Tuple2!::getT2)
 .flatMap(repository!::save)
 .subscribe(); String[] names = { "Eddard", "Catelyn", "Jon", "Rob", "Sansa", "Aria", "Bran", "Rickon" };
 Flux<Person> starks = Flux
 .fromStream(Stream.generate(() !-> 
 names[ramdom.nextInt(names.length)])
 .map(Person!::new));
  16. Spring Data Reactive - Repository 16 Unless otherwise indicated, these

    slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { } Flux.interval(Duration.ofSeconds(1))
 .zipWith(starks)
 .map(Tuple2!::getT2)
 .flatMap(repository!::save)
 .subscribe(); String[] names = { "Eddard", "Catelyn", "Jon", "Rob", "Sansa", "Aria", "Bran", "Rickon" };
 Flux<Person> starks = Flux
 .fromStream(Stream.generate(() !-> 
 names[ramdom.nextInt(names.length-1)])
 .map(Person!::new)); > cstrobl $ ./bin/mongo --port 52291 > use test switched to db test { "_id" : ObjectId("591009c5ed68a820fb9956a5"), "name" : "Sansa", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009c6ed68a820fb9956a6"), "name" : "Rob", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009c7ed68a820fb9956a7"), "name" : "Sansa", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009c8ed68a820fb9956a8"), "name" : "Rob", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009c9ed68a820fb9956a9"), "name" : "Jon", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009caed68a820fb9956aa"), "name" : "Aria", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009cbed68a820fb9956ab"), "name" : "Rob", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009cced68a820fb9956ac"), "name" : "Jon", "_class" : "com.example.DemoApplication$Person" } { "_id" : ObjectId("591009cded68a820fb9956ad"), "name" : "Sansa", "_class" : "com.example.DemoApplication$Person" } > db.person.find();
  17. Spring Data Reactive - WebFlux 17 Unless otherwise indicated, these

    slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { Flux<Person> findAllByName(String name); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 
 
 
 
 
 } @GetMapping("/")
 Flux<Person> fluxPersons(String name) {
 return repository.findAllByName(name);
 }

  18. Spring Data Reactive - WebFlux 18 Unless otherwise indicated, these

    slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { Flux<Person> findAllByName(String name); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 
 
 
 
 
 } @GetMapping("/")
 Flux<Person> fluxPersons(String name) {
 return repository.findAllByName(name);
 }
 > cstrobl $ curl localhost:8080/?name=Eddard | jq [ { "name": "Eddard", "id": "591014f2756bac231a23f3a0" }, { "name": "Eddard", "id": "591014f7756bac231a23f3a5" } ] >
  19. Spring Data Reactive - RxJava types 19 Unless otherwise indicated,

    these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { Observable<Person> findByName(String name); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 @GetMapping("/rx")
 Observable<Person> rxPersons(String name) {
 return repository.findByName(name);
 }
 }
  20. Spring Data Reactive - RxJava types 20 Unless otherwise indicated,

    these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { Observable<Person> findByName(String name); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 @GetMapping("/rx")
 Observable<Person> rxPersons(String name) {
 return repository.findByName(name);
 }
 } > cstrobl $ curl localhost:8080/rx?name=Rob | jq [ { "name": "Rob", "id": "590f6e99756bac18a8d62bfe" }, { "name": "Rob", "id": "590f6e9d756bac18a8d62c02" } { "name": "Rob", "id": "590f6e9e756bac18a8d62c03" } ] >
  21. Spring Data Reactive - Event Stream 21 Unless otherwise indicated,

    these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { @Tailable Flux<Person> findBy(); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) Flux<Person> streamPersons() {
 return repository.findBy();
 }
 }
  22. Spring Data Reactive - Event Stream 22 Unless otherwise indicated,

    these slides are © 2013-2017 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface PersonRepository extends ReactiveCrudRepository<Person, String> { @Tailable Flux<Person> findBy(); } @RestController
 static class PersonController {
 
 PersonRepository repository;
 
 @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) Flux<Person> streamPersons() {
 return repository.findBy();
 }
 } > cstrobl $ curl localhost:8080/stream data:{"name":"Sansa","id":"5910192e756bac26079dd623"} data:{"name":"Jon","id":"5910192f756bac26079dd624"} data:{"name":"Catelyn","id":"59101930756bac26079dd625"} data:{"name":"Eddard","id":"59101931756bac26079dd626"} data:{"name":"Jon","id":"59101932756bac26079dd627"} data:{"name":"Eddard","id":"59101933756bac26079dd628"}
  23. 23 Unless otherwise indicated, these slides are © 2013-2017 Pivotal

    Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ …give it a try!
 …tell us what you think!
 …contribute new ideas!
 …report issues! Spring 5 Spring Boot 2 Spring Data Kay We need you!