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

    View Slide

  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

    View Slide

  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/
    {…}

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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)

    View Slide

  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 (0…n)
    Flux (0…n) Mono (0…1)
    Reactive Streams

    View Slide

  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);

    View Slide

  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();

    View Slide

  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

    View Slide

  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

    */

    Flux findAll(Class 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

    */

    Mono findOne(Query query, Class entityClass);

    View Slide

  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 {
    }
    Flux findAllByLastname(String lastname);
    Flux findAllByLastname(Mono lastname);
    Flux customQuery(String lastname);
    @Query("{lastname : ?0}");
    Flux findAllByLastname(String ln, Pageable page);

    View Slide

  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

    View Slide

  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 {
    }
    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 starks = Flux

    .fromStream(Stream.generate(() !-> 

    names[ramdom.nextInt(names.length)])

    .map(Person!::new));

    View Slide

  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 {
    }
    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 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();

    View Slide

  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 {
    Flux findAllByName(String name);
    }
    @RestController

    static class PersonController {


    PersonRepository repository;







    }
    @GetMapping("/")

    Flux fluxPersons(String name) {

    return repository.findAllByName(name);

    }


    View Slide

  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 {
    Flux findAllByName(String name);
    }
    @RestController

    static class PersonController {


    PersonRepository repository;







    }
    @GetMapping("/")

    Flux fluxPersons(String name) {

    return repository.findAllByName(name);

    }

    > cstrobl $ curl localhost:8080/?name=Eddard | jq
    [
    {
    "name": "Eddard",
    "id": "591014f2756bac231a23f3a0"
    },
    {
    "name": "Eddard",
    "id": "591014f7756bac231a23f3a5"
    }
    ]
    >

    View Slide

  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 {
    Observable findByName(String name);
    }
    @RestController

    static class PersonController {


    PersonRepository repository;


    @GetMapping("/rx")

    Observable rxPersons(String name) {

    return repository.findByName(name);

    }

    }

    View Slide

  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 {
    Observable findByName(String name);
    }
    @RestController

    static class PersonController {


    PersonRepository repository;


    @GetMapping("/rx")

    Observable 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"
    }
    ]
    >

    View Slide

  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 {
    @Tailable Flux findBy();
    }
    @RestController

    static class PersonController {


    PersonRepository repository;


    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    Flux streamPersons() {

    return repository.findBy();

    }

    }

    View Slide

  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 {
    @Tailable Flux findBy();
    }
    @RestController

    static class PersonController {


    PersonRepository repository;


    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    Flux 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"}

    View Slide

  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!

    View Slide