SlideShare a Scribd company logo
1 of 65
Download to read offline
Reactive Programming in Java and Spring 5
Richard Langlois P. Eng., Solutions Architect
January 24th, 2018
>
• Introduction to Reactive Programming
• Reactive Manifesto
• Reactive Streams Specification
• Reactor
• Reactive Programming with Spring 5
• Reactive Spring Data
Agenda
>
• Is a programming paradigm.
• Is about:
• Non-blocking applications which are
• asynchronous
• even-driven
• require a small amount of threads to scale vertically (within the JVM).
Introduction to Reactive Programming
>
From Merriam Webster: “Readily responsive to a stimulus”
• React to events (event-driven)
• React to load (scalable)
• React to failures (resilient)
• React to users (responsive)
Key to understand reactive programming is to think about it as operating on a stream of data.
Steam of data meaning a sequence of events, where an event could be
• user input (like a tap on a button),
• a response from an API request (like a Facebook feed),
• data contained in a database,
• a single variable.
Reactive
>
Reactive Manifesto is a prescription for building modern, cloud scale architecture, which is well prepared to meet the increasing
demands that applications face today.
Homepage: http://reactivemanifesto.org/
Reactive Manifesto
>
The Four Reactive Traits:
• Responsive: Application provides rich, real-time interaction with its users even under load and in the presence of failures.
• Resilient: Application recover quickly from failure (e.g. software, hardware, connections).
• Scalable: Application is able to be expanded according to its usage
• scale up: make use of more powerful hardware (aka vertical scaling)
• scale out: make use of multiple server nodes (aka horizontal scaling)
• Event-Driven: Application is composed of loosely coupled event handlers. Events can be handled asynchronously, without
blocking.
Reactive Manifesto
Characteristics
>
Reactive Streams is a Standard and specification for Stream‐oriented libraries for the JVM that
• process a potentially unbounded number of elements in sequence
• asynchronously passing elements between components
• with mandatory non‐blocking backpressure.
Specification consists of the following parts:
• The API specifies the types to implement Reactive Streams and achieve interoperability between different implementations.
• The Technology Compatibility Kit (TCK): a standard test suite for conformance testing of implementations.
Reactive Streams are only concerned with mediating the stream of data between different API Components (so operators
are not specified).
Reactive Streams specification
>
Allows to control the amount of inflight data
Regulate the transfer between:
• Slow publisher and fast consumer
• Fast publisher and slow consumer
Back Pressure (a.k.a. Flow Control)
>
Reactive Streams Specification
API
>
Those interfaces are included in Java 9 (under java.util.concurrent):
• Flow.Publisher
• Flow.Subscriber
• Flow.Subscription
• Flow.Processor
Reactive Streams Specification
Java 9
>
API Explanation:
• Communication between publisher and subscriber is set up via the publisher’s subscribe(), through which the two parties
are introduced to each other.
• After successful initialization of the communication, the subscriber gets to know about a Subscription (which models the
established connection) via a call to its onSubscribe method.
• At the core of the Reactive Streams mechanism is the request method of the Subscription. Through the request() method,
the subscriber signals to the publisher how many elements it’s ready to process.
• The publisher communicates every element one by one to the subscriber via its onNext() method, as well as fatal stream
failures through the onError() method.
• Because the publisher knows exactly how many items it’s expected to publish at any time (it has been asked for a number of
elements in the Subscription’s request method), it’s able to produce as many elements as required without producing too
many for the subscriber to consume, eliminating the need to block while waiting for the subscriber.
• Additionally, the subscriber is called by the publisher for each published element through the onNext() method, meaning
that it does not explicitly need to block while waiting for new elements to be available.
Reactive Streams Specification
>
Some Reactive Libraries on the JVM:
• RxJava: Reactive Extensions implemented on the JVM.
• Akka Streams
• Reactor Core:
Reactive Stream Specification
>
Is a fourth-generation Reactive library for building non-blocking applications on the
JVM based on the Reactive Streams Specification.
• Targets Java 8.
• Extends a Reactive Streams Publisher with the Flux and Mono API types.
It adds the concept of operators, which are chained together to describe what processing to apply at
each stage to the data.
Applying an operator returns a new intermediate Publisher.
Reactor
Core 3
>
Reactor
Evolution
>
Flux:
• A Flux<T> is a standard Publisher<T> representing an asynchronous sequence of 0 to N emitted
items, optionally terminated by either a completion signal or an error.
• Possible values of a flux: a value, a completion signal, an error.
• Translates to calls to a downstream object’s onNext, onComplete, onError methods.
• Marble diagram:
Reactor
Core Features
>
Mono:
• A Mono is a standard Publisher<T> that emits at most one item and then optionally terminates with
an onComplete signal or an onError signal.
• It offers only a subset of the operators that are available for a Flux.
• Can represent no-value asynchronous processes which have the concept of completion
(Mono<void>).
Reactor
Core Features
>
Numerous factory methods:
• Flux<String> seq1 = Flux.just("foo", "bar", "foobar");
• private static List<String> iterable = Arrays.asList ("foo", "bar", "foobar");
Flux<String> fluxFromIterable = Flux.fromIterable(iterable);
• Mono<String> noData = Mono.empty();
• Mono<String> data = Mono.just("foo");
• Flux<Integer> numbersFromFiveToSeven = Flux.range(5, 3); // 1st parameter is start of the range, 2nd is number of items
Reactor
Flux or Mono Creation
>
.subscribe variants take lambdas for different combination of callbacks:
1. subscribe(); // subscribe and trigger the sequence
2. subscribe(Consumer<? super T> consumer); // consumer run when values
3. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer); // consumer run when error
4. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer, // Consumer run when error
Runnable completeConsumer); // consumer run when sequence successfully complete
5. subscribe(Consumer<? super T> consumer, // deal with values
Consumer<? super Throwable> errorConsumer, // consumer run when error
Runnable completeConsumer, // consumer run when the sequence successfully complete
Consumer<? super Subscription> subscriptionConsumer); // consumer run when subscription produced
Reactor - Subscribe
>
Example:
// Use the subscribe() method to collect all the elements in a stream
Flux<Integer> elementsFlux = Flux.just(1, 2, 3, 4);
// subscribe with a subscriber that will print the values, The data will not start flowing until we subscribe
elementsFlux().subscribe(System.out::println(i));
Logs:
[main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | request(unbounded)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(1)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(2)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(3)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(4)
20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onComplete()
Reactor - Subscribe
>
Example: Tell upstream to only send 2 elements at a time by using request().
Flux.just(1, 2, 3, 4)
.log()
.subscribe(new Subscriber<Integer>() {
private Subscription s;
int onNextAmount;
@Override
public void onSubscribe(Subscription s) {
this.s = s;
s.request(2);
}
…
Reactor – Back Pressure
Example (1 of 3)
>
…
@Override
public void onNext(Integer integer) {
elements.add(integer);
onNextAmount++;
if (onNextAmount % 2 == 0) {
s.request(2);
}
}
@Override
public void onError(Throwable t) {}
@Override
public void onComplete() {}
});
Reactor – Back Pressure
Example (2 of 3)
>
Logs:
23:31:15.395 [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription)
23:31:15.397 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.397 [main] INFO reactor.Flux.Array.1 - | onNext(1)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(3)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(4)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2)
23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onComplete()
Notice:
The request(2) is called (when Subscribing), followed by two onNext() calls, then request(2) again, then on Complete().
Reactor – Back Pressure
Example (3 of 3)
>
Reactive Operators applies a wide range of transformations to the sequence of data (e.g. Map, Flatmap, Filter, Concat, Merge,
buffer, split, transform, delay …)
Special diagrams called Marble Diagrams efficiently explains what an operator does, for example:
Reactor - Reactive Operators
>
Map: Transform every item of the emitted sequence with a specified function.
Reactor – Reactive Operators
Map()
>
Concat:
concatenates 2 or more emissions, generating one emission where all the items from the 1st source emission appear before the
items of the 2nd source emission.
Reactor - Reactive Operators
Concat()
>
flatMap():
performs 2 types of actions:
1. the “map” action that transforms the emitted item into Flux
2. The “flatten” action that converts those Flux into one Flux.
Reactor - Reactive Operators
flatMap
>
Merge:
When we want to get feeds from multiple sources as one stream.
Reactor - Reactive Operators
merge()
>
Zip:
takes multiple observables as inputs and combines each emission via a specified function
and emits the results of this function as a new sequence.
Reactor - Reactive Operators
zip()
>
StepVerifier API:
• Builder API allowing to test how a Flux or Mono behave when subscribed to.
Some methods:
• expectNext()
• expectError()
• expectErrorMessage()
• expectComplete()
• Verify(), VerifyComplete(), VerifyError(), VerifyErrorMessage()
Reactor - Testing
StepVerifier
>
Example:
// empty Flux
Flux<String> emptyFlux = Flux.empty();
StepVerifier.create(emptyFlux).verifyComplete();
// non-empty Flux
Flux<String> nonEmptyFlux = Flux.just("John", "Mike", "Sarah");
StepVerifier.create(nonEmptyFlux).expectNext("John", "Mike", "Sarah").verify();
Call to verify():
• triggers the verification by subscribing to the Flux/Mono under test.
• Plays the sequence, comparing each new signal with the next step in the scenario
• As long as these match, the test is considered a success, else, an AssertionError is thrown.
Reactor - Testing
StepVerifier
>
• New spring-webflux module to support reactive HTTP client-side and server-side.
• Uses Reactor internally for its own reactive support.
Spring Framework 5
Reactive Support
>
Spring 5
Reactive and Servlet Stack
>
Add Dependency to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Spring 5
WebFlux
>
• Supports 2 distinct programming models:
• Annotation-based with @Controller and the other annotations of Spring MVC
• Functional Style routing and handling with Java 8 lambda.
Spring 5
Server Side
>
Example:
@RestController
@RequestMapping(value="/api/customer")
public class RestControllerAPIs {
@GetMapping("/")
public Flux<Customer> getAll() {
...
}
@GetMapping("/{id}")
public Mono<Customer> getCustomer(@PathVariable Long id) {
...
}
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Get all customers test case:
Map<Long, Customer> custStores = new HashMap<Long, Customer>();
…
@GetMapping
public Flux<Customer> getAll() {
return Flux.fromIterable(custStores.entrySet().stream()
.map(entry -> entry.getValue())
.collect(Collectors.toList()));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Get a customer test case:
@GetMapping("/{id}")
public Mono<Customer> getCustomer(@PathVariable Long id) {
return Mono.justOrEmpty(custStores.get(id));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Create a customer test case:
@PostMapping("/post")
public Mono<ResponseEntity<String>> postCustomer(@RequestBody Customer customer) {
// do post
custStores.put(customer.getCustId(), customer);
return Mono.just(new ResponseEntity<>("Post Successfully!", HttpStatus.CREATED));
}
Spring 5 - WebFlux
Server Side - Annotation-based - Example
>
Framework introduces 2 fundamental components:
• Routes a given HTTP requests via a RouterFunction (alternative to using annotations like @RequestMapping)
• Handles the request via HandlerFunction (alternative to @Controller’s handler methods).
RouterFunction utility classes are used to create RouterFunction:
e.g.
RouterFunction.route(RequestPredicate, HandlerFunction):
• helper function to create routes.
• Allows to route requests by applying a RequestPredicate.
• When the predicate is matched, then the second argument is run.
Spring 5 - WebFlux
Server Side - Functional Style
>
Example:
RouterFunction router = route( GET("/test"),
request -> ok().build() ) ;
• GET("/test") is the RequestPredicate.
• req -> ok().build() is the handler producing the response.
Spring 5
Server Side – Functional Style
>
WebClient
• Is a reactive client for performing HTTP requests with Reactive Streams back
pressure.
• Is replacing the classic RestTemplate.
• Is an interface which has a single implementation – DefaultWebClient class.
Usage(similar to HttpClient):
1. Create an instance
2. Make a request
3. Handle the reponse
Spring 5
Client side
>
Create WebClient using one of the 3 options :
• With default settings:
• WebClient client1 = WebClient.create();
• With a given base URI:
• WebClient client2 = WebClient.create("http://localhost:8080 (http://localhost:8080)");
• Using the DefaultWebClientBuilder class:
• WebClient client3 = WebClient
.builder()
.baseUrl("http://localhost:8080 (http://localhost:8080)")
.defaultCookie("cookieKey", "cookieValue")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080 (http://localhost:8080)"))
.build();
Spring 5
Client side - WebClient
>
// Setting a request body
//where a Publisher is a reactive component that is in charge of providing a potentially unbounded number of sequenced
elements.
WebClient.RequestHeadersSpec requestSpec1
= WebClient.create()
.method(HttpMethod.POST)
.uri("/resource")
.body(BodyInserters.fromPublisher(Mono.just("data")), String.class);
WebClient.RequestHeadersSpec<?> requestSpec2
= WebClient.create("http://localhost:8080 (http://localhost:8080)")
.post()
.uri(URI.create("/resource"))
.body(BodyInserters.fromObject("data"));
Spring 5
Client side - WebClient
>
A Response is obtained with exchange() or retrieve():
• exchange(): provides a ClientResponse along with its status, headers
• retrieve(): fetches a body directly
Example:
String response2 = request1.exchange()
.block()
.bodyToMono(String.class)
.block();
String response3 = request2.retrieve()
.bodyToMono(String.class)
.block();
Note: The block method on Monos is used to subscribe and retrieve an actual data which was sent with the response.
Spring 5
Client side - WebClient
>
WebTestClient
• is a non-blocking, reactive client for Spring-webflux integration testing support.
• Offers an identical API as the WebClient.
• can connect to any server over an HTTP connection.
• provides a fluent API to verify responses.
• can also bind directly to WebFlux applications with mock request and response objects.
Spring 5
Spring WebFlux Testing
>
Add Test dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
Spring 5
Spring WebFlux Testing
>
@WebFluxTest:
• auto-configures WebTestClient to quickly test WebFlux controllers without starting
a full HTTP server
Example of an unit test:
@RunWith(SpringRunner.class)
@WebFluxTest
public class SpringWebFluxTestApplicationTests {
@Autowired
private WebTestClient webTestClient;
…
}
Spring 5 - WebFlux
Testing
>
Test without starting an actual server:
WebTestClient client
= WebTestClient.bindToRouterFunction(routingFunction())
.build();
client.get().uri("/").exchange()
.expectStatus().isOk(); // Assert
Test with a real server:
WebTestClient client
= WebTestClient.bindToServer()
.baseUrl("http://localhost:8080 (http://localhost:8080)")
.build();
client.get().uri("/").exchange()
.expectStatus().isOk(); // Assert
Spring 5 - WebFlux
WebTestClient
>
Get test case:
Using WebTestClient API:
webTestClient.get().uri("/api/customer/{id}", 2).accept(MediaType.APPLICATION_JSON).exchange()
.expectStatus().isOk().expectBody(Customer.class).isEqualTo(customerMap.get("Peter")); // Assert
Using RouterFunction:
// The Router Function
RouterFunction myRouterFunction = route(GET("/test"), // RouterFunction
request -> ok().body(fromObject("hello world"))); // HandlerFunction
// Register the RouterFunction
WebTestClient webTestClient = WebTestClient.bindToRouterFunction(myRouterFunction).build();
// Assert the response
webTestClient.get().uri("/test").exchange().expectStatus().isOk();
Spring 5
WebTestClient - Example
>
POST test case:
webTestClient
// Create a POST request
.post()
.uri("/api/customer/post")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject(customerMap.get("Mary")))
.exchange()
// Assert the response
.expectStatus().isCreated()
.expectBody(String.class)
.isEqualTo("Post Successfully!");
Spring 5
WebTestClient - Example
>
PUT test case:
webTestClient
// Create a PUT request
.put().uri("/api/customer/put/{id}", 3)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject(customerMap.get("Amy")))
.exchange()
// Assert the response
.expectStatus().isCreated()
.expectBody(Customer.class)
isEqualTo(customerMap.get("Amy"));
Spring 5
WebTestClient - Example
>
DELETE test case:
webTestClient
// Create a DELETE request
.delete().uri("/api/customer/delete/{id}", 1)
.exchange()
// Assert the response
.expectStatus().isAccepted()
.expectBody(String.class)
.isEqualTo("Delete Succesfully!");
Spring 5
WebTestClient - Example
>
Spring WebFlux is supported on the following servers:
• Netty
• Undertow
• Tomcat
• Jetty
• Servlet 3.1+ containers
Spring Boot 2 uses Netty by default with WebFlux
Spring 5
Choosing a server
>
• Asynchronous
• Non Blocking
• Event Driven
• Data as stream
Reactive Data Access
>
Spring Data support Reactive Streams
Reactive Spring Data Modules:
• MongoDb
• Redis
• Cassandra
• CouchDB
Reactive Spring Data
>
Lets see an example based on Spring Data and MongoDB
Spring Data - MongoDB
>
Getting up a running Reactive Streams with Spring Data and MongoDB:
• Add the dependency (in pom.xml)
• Configuration (@EnableReactiveMongoRepositories)
• Repository interface (extends ReactiveMongoRepository, and use Flux and Mono
types)
Spring Data - MongoDB
>
Add Reactive MongoDB to our pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>http://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
Spring Data - MongoDB
Example
>
@Configuration
@EnableReactiveMongoRepositories(basePackageClasses = PersonRepository.class)
public class MongoConfig extends AbstractReactiveMongoConfiguration {
@Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
@Override
protected String getDatabaseName() {
return "test";
}
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient(), getDatabaseName());
}
}
Spring Data – MongoDB
Example - Configuration
>
Configuration:
@EnableMongoRepositories enable the use of ReactiveCrudRepository.
For example:
• Mono<S> = save(S entity)
• Mono<T> = findById(ID id)
• Mono<T> = findById(Publisher<ID> id)
• Uses the first emitted element to perform the find-query
• Mono<void> = deleteById(ID id)
• Mono signaling when operation is completed
Spring Data – MongoDB
Example
>
Repository:
@EnableMongoRepositories enable the use of ReactiveCrudRepository.
public interface PersonRepository extends ReactiveMongoRepository<Person, String> {
Flux<Person> findByFirstName(final String firstName);
Mono<Person> findOneByFirstName(final String firstName);
Mono<void> = deleteById(ID id); //Mono signaling when operation is completed
}
Notice:
• Flux<Person> replaces the use of List
• Mono<Person> is used instead of Person.
This allows to perform functions on each element as they come from MongoDB database, instead of waiting until
all records are returned, and then do something with them.
Spring Data – MongoD
Example
>
Application:
@SpringBootApplication
public class Application implements CommandLineRunner {
…
@Override
public void run(String args[]) {
final Person johnAoe = new Person("john", "aoe", LocalDateTime.now(), "loser", 0);
final Person johnBoe = new Person("john", "boe", LocalDateTime.now(), "a bit of a lose
personRepository.saveAll(Flux.just(johnAoe, johnBoe)).subscribe();
personRepository.findByFirstName("john").log().map(Person::getSecondName)
.subscribe(System.out::println);
personRepository.findOneByFirstName("john").log().map(Person::getId)
.subscribe(System.out::println);
}
}
Spring Data – MongoD
Example
>
Associated Logs:
2017-07-16 16:44:09.201 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
2017-07-16 16:44:09.208 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : request(unbounded)
2017-07-16 16:44:09.242 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0))
aoe
2017-07-16 16:44:09.243 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=boe, profession=a bit of a loser,
salary=10))
boe
2017-07-16 16:44:09.247 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onComplete()
2017-07-16 16:44:09.254 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
2017-07-16 16:44:09.255 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : request(unbounded)
2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0))
596b89c97ab38934a404a80c
2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onComplete()
Spring Data – MongoD
Example
>
• The Reactive Manifesto:
• https://www.reactivemanifesto.org/
• Reactor:
• https://projectreactor.io/
• Spring WebFlux:
• https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html
• Going reactive with Spring Data:
• https://spring.io/blog/2016/11/28/going-reactive-with-spring-data
• Servlet vs Reactive Stacks in Five Use Cases:
• https://www.infoq.com/presentations/servlet-reactive-stack
References
>
Thank You!

More Related Content

What's hot

Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorMax Huang
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Toshiaki Maki
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
Microservices with Spring 5 Webflux - jProfessionals
Microservices  with Spring 5 Webflux - jProfessionalsMicroservices  with Spring 5 Webflux - jProfessionals
Microservices with Spring 5 Webflux - jProfessionalsTrayan Iliev
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Graphql presentation
Graphql presentationGraphql presentation
Graphql presentationVibhor Grover
 
Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programmingDwi Randy Herdinanto
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud VMware Tanzu
 
REST API Best (Recommended) Practices
REST API Best (Recommended) PracticesREST API Best (Recommended) Practices
REST API Best (Recommended) PracticesRasheed Waraich
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive ProgrammingStéphane Maldini
 
Swagger / Quick Start Guide
Swagger / Quick Start GuideSwagger / Quick Start Guide
Swagger / Quick Start GuideAndrii Gakhov
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use CasesAlex Soto
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSAbul Hasan
 

What's hot (20)

Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
React & GraphQL
React & GraphQLReact & GraphQL
React & GraphQL
 
Project Reactor By Example
Project Reactor By ExampleProject Reactor By Example
Project Reactor By Example
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Microservices with Spring 5 Webflux - jProfessionals
Microservices  with Spring 5 Webflux - jProfessionalsMicroservices  with Spring 5 Webflux - jProfessionals
Microservices with Spring 5 Webflux - jProfessionals
 
Swagger UI
Swagger UISwagger UI
Swagger UI
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Graphql presentation
Graphql presentationGraphql presentation
Graphql presentation
 
Introduction to Reactive programming
Introduction to Reactive programmingIntroduction to Reactive programming
Introduction to Reactive programming
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud
 
Spring GraphQL
Spring GraphQLSpring GraphQL
Spring GraphQL
 
REST API Best (Recommended) Practices
REST API Best (Recommended) PracticesREST API Best (Recommended) Practices
REST API Best (Recommended) Practices
 
Intro to Reactive Programming
Intro to Reactive ProgrammingIntro to Reactive Programming
Intro to Reactive Programming
 
Swagger / Quick Start Guide
Swagger / Quick Start GuideSwagger / Quick Start Guide
Swagger / Quick Start Guide
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use Cases
 
Spring boot
Spring bootSpring boot
Spring boot
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Angular Observables & RxJS Introduction
Angular Observables & RxJS IntroductionAngular Observables & RxJS Introduction
Angular Observables & RxJS Introduction
 

Similar to Reactive Programming in Java and Spring 5 with Reactor Core

Functional reactive programming
Functional reactive programmingFunctional reactive programming
Functional reactive programmingAraf Karsh Hamid
 
Journey into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsJourney into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsKevin Webber
 
Microservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive ProgrammingMicroservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive ProgrammingAraf Karsh Hamid
 
Guide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFluxGuide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFluxInexture Solutions
 
Reactive Streams and RxJava2
Reactive Streams and RxJava2Reactive Streams and RxJava2
Reactive Streams and RxJava2Yakov Fain
 
Multi-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketMulti-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketStéphane Maldini
 
Reactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactorReactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactorOrenEzer1
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorStéphane Maldini
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorVMware Tanzu
 
Spring 5 Webflux - Advances in Java 2018
Spring 5 Webflux - Advances in Java 2018Spring 5 Webflux - Advances in Java 2018
Spring 5 Webflux - Advances in Java 2018Trayan Iliev
 
Reactive Streams 1.0.0 and Why You Should Care (webinar)
Reactive Streams 1.0.0 and Why You Should Care (webinar)Reactive Streams 1.0.0 and Why You Should Care (webinar)
Reactive Streams 1.0.0 and Why You Should Care (webinar)Legacy Typesafe (now Lightbend)
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootVMware Tanzu
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & designallegro.tech
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCKonrad Malawski
 
Android reactive programming using agera
Android reactive programming using ageraAndroid reactive programming using agera
Android reactive programming using ageraMahmoud El-Naggar
 

Similar to Reactive Programming in Java and Spring 5 with Reactor Core (20)

Functional reactive programming
Functional reactive programmingFunctional reactive programming
Functional reactive programming
 
Journey into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka StreamsJourney into Reactive Streams and Akka Streams
Journey into Reactive Streams and Akka Streams
 
Microservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive ProgrammingMicroservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive Programming
 
Guide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFluxGuide to Spring Reactive Programming using WebFlux
Guide to Spring Reactive Programming using WebFlux
 
Reactive Streams and RxJava2
Reactive Streams and RxJava2Reactive Streams and RxJava2
Reactive Streams and RxJava2
 
Multi-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocketMulti-service reactive streams using Spring, Reactor, RSocket
Multi-service reactive streams using Spring, Reactor, RSocket
 
Reactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactorReactive solutions using java 9 and spring reactor
Reactive solutions using java 9 and spring reactor
 
Springone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and ReactorSpringone2gx 2014 Reactive Streams and Reactor
Springone2gx 2014 Reactive Streams and Reactor
 
Introduction to reactive programming
Introduction to reactive programmingIntroduction to reactive programming
Introduction to reactive programming
 
Reactive mesh
Reactive meshReactive mesh
Reactive mesh
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
 
Spring 5 Webflux - Advances in Java 2018
Spring 5 Webflux - Advances in Java 2018Spring 5 Webflux - Advances in Java 2018
Spring 5 Webflux - Advances in Java 2018
 
Reactors.io
Reactors.ioReactors.io
Reactors.io
 
Reactive Spring 5
Reactive Spring 5Reactive Spring 5
Reactive Spring 5
 
Reactive Streams 1.0.0 and Why You Should Care (webinar)
Reactive Streams 1.0.0 and Why You Should Care (webinar)Reactive Streams 1.0.0 and Why You Should Care (webinar)
Reactive Streams 1.0.0 and Why You Should Care (webinar)
 
Reactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring BootReactive Applications with Apache Pulsar and Spring Boot
Reactive Applications with Apache Pulsar and Spring Boot
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
 
Android reactive programming using agera
Android reactive programming using ageraAndroid reactive programming using agera
Android reactive programming using agera
 

More from Richard Langlois P. Eng.

More from Richard Langlois P. Eng. (7)

Monitoring with Prometheus
Monitoring with PrometheusMonitoring with Prometheus
Monitoring with Prometheus
 
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
Continuous Test Automation, by Richard Langlois P. Eng. and Yuri Pechenko.
 
Microservice Architecture Patterns, by Richard Langlois P. Eng.
Microservice Architecture Patterns, by Richard Langlois P. Eng.Microservice Architecture Patterns, by Richard Langlois P. Eng.
Microservice Architecture Patterns, by Richard Langlois P. Eng.
 
What's New in Java 9
What's New in Java 9What's New in Java 9
What's New in Java 9
 
DevOps, Yet Another IT Revolution
DevOps, Yet Another IT RevolutionDevOps, Yet Another IT Revolution
DevOps, Yet Another IT Revolution
 
What is new in JUnit5
What is new in JUnit5What is new in JUnit5
What is new in JUnit5
 
Introduction to Reactive Microservices Architecture.
Introduction to Reactive Microservices Architecture.Introduction to Reactive Microservices Architecture.
Introduction to Reactive Microservices Architecture.
 

Recently uploaded

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 

Reactive Programming in Java and Spring 5 with Reactor Core

  • 1. Reactive Programming in Java and Spring 5 Richard Langlois P. Eng., Solutions Architect January 24th, 2018
  • 2. > • Introduction to Reactive Programming • Reactive Manifesto • Reactive Streams Specification • Reactor • Reactive Programming with Spring 5 • Reactive Spring Data Agenda
  • 3. > • Is a programming paradigm. • Is about: • Non-blocking applications which are • asynchronous • even-driven • require a small amount of threads to scale vertically (within the JVM). Introduction to Reactive Programming
  • 4. > From Merriam Webster: “Readily responsive to a stimulus” • React to events (event-driven) • React to load (scalable) • React to failures (resilient) • React to users (responsive) Key to understand reactive programming is to think about it as operating on a stream of data. Steam of data meaning a sequence of events, where an event could be • user input (like a tap on a button), • a response from an API request (like a Facebook feed), • data contained in a database, • a single variable. Reactive
  • 5. > Reactive Manifesto is a prescription for building modern, cloud scale architecture, which is well prepared to meet the increasing demands that applications face today. Homepage: http://reactivemanifesto.org/ Reactive Manifesto
  • 6. > The Four Reactive Traits: • Responsive: Application provides rich, real-time interaction with its users even under load and in the presence of failures. • Resilient: Application recover quickly from failure (e.g. software, hardware, connections). • Scalable: Application is able to be expanded according to its usage • scale up: make use of more powerful hardware (aka vertical scaling) • scale out: make use of multiple server nodes (aka horizontal scaling) • Event-Driven: Application is composed of loosely coupled event handlers. Events can be handled asynchronously, without blocking. Reactive Manifesto Characteristics
  • 7. > Reactive Streams is a Standard and specification for Stream‐oriented libraries for the JVM that • process a potentially unbounded number of elements in sequence • asynchronously passing elements between components • with mandatory non‐blocking backpressure. Specification consists of the following parts: • The API specifies the types to implement Reactive Streams and achieve interoperability between different implementations. • The Technology Compatibility Kit (TCK): a standard test suite for conformance testing of implementations. Reactive Streams are only concerned with mediating the stream of data between different API Components (so operators are not specified). Reactive Streams specification
  • 8. > Allows to control the amount of inflight data Regulate the transfer between: • Slow publisher and fast consumer • Fast publisher and slow consumer Back Pressure (a.k.a. Flow Control)
  • 10. > Those interfaces are included in Java 9 (under java.util.concurrent): • Flow.Publisher • Flow.Subscriber • Flow.Subscription • Flow.Processor Reactive Streams Specification Java 9
  • 11. > API Explanation: • Communication between publisher and subscriber is set up via the publisher’s subscribe(), through which the two parties are introduced to each other. • After successful initialization of the communication, the subscriber gets to know about a Subscription (which models the established connection) via a call to its onSubscribe method. • At the core of the Reactive Streams mechanism is the request method of the Subscription. Through the request() method, the subscriber signals to the publisher how many elements it’s ready to process. • The publisher communicates every element one by one to the subscriber via its onNext() method, as well as fatal stream failures through the onError() method. • Because the publisher knows exactly how many items it’s expected to publish at any time (it has been asked for a number of elements in the Subscription’s request method), it’s able to produce as many elements as required without producing too many for the subscriber to consume, eliminating the need to block while waiting for the subscriber. • Additionally, the subscriber is called by the publisher for each published element through the onNext() method, meaning that it does not explicitly need to block while waiting for new elements to be available. Reactive Streams Specification
  • 12. > Some Reactive Libraries on the JVM: • RxJava: Reactive Extensions implemented on the JVM. • Akka Streams • Reactor Core: Reactive Stream Specification
  • 13. > Is a fourth-generation Reactive library for building non-blocking applications on the JVM based on the Reactive Streams Specification. • Targets Java 8. • Extends a Reactive Streams Publisher with the Flux and Mono API types. It adds the concept of operators, which are chained together to describe what processing to apply at each stage to the data. Applying an operator returns a new intermediate Publisher. Reactor Core 3
  • 15. > Flux: • A Flux<T> is a standard Publisher<T> representing an asynchronous sequence of 0 to N emitted items, optionally terminated by either a completion signal or an error. • Possible values of a flux: a value, a completion signal, an error. • Translates to calls to a downstream object’s onNext, onComplete, onError methods. • Marble diagram: Reactor Core Features
  • 16. > Mono: • A Mono is a standard Publisher<T> that emits at most one item and then optionally terminates with an onComplete signal or an onError signal. • It offers only a subset of the operators that are available for a Flux. • Can represent no-value asynchronous processes which have the concept of completion (Mono<void>). Reactor Core Features
  • 17. > Numerous factory methods: • Flux<String> seq1 = Flux.just("foo", "bar", "foobar"); • private static List<String> iterable = Arrays.asList ("foo", "bar", "foobar"); Flux<String> fluxFromIterable = Flux.fromIterable(iterable); • Mono<String> noData = Mono.empty(); • Mono<String> data = Mono.just("foo"); • Flux<Integer> numbersFromFiveToSeven = Flux.range(5, 3); // 1st parameter is start of the range, 2nd is number of items Reactor Flux or Mono Creation
  • 18. > .subscribe variants take lambdas for different combination of callbacks: 1. subscribe(); // subscribe and trigger the sequence 2. subscribe(Consumer<? super T> consumer); // consumer run when values 3. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer); // consumer run when error 4. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer, // Consumer run when error Runnable completeConsumer); // consumer run when sequence successfully complete 5. subscribe(Consumer<? super T> consumer, // deal with values Consumer<? super Throwable> errorConsumer, // consumer run when error Runnable completeConsumer, // consumer run when the sequence successfully complete Consumer<? super Subscription> subscriptionConsumer); // consumer run when subscription produced Reactor - Subscribe
  • 19. > Example: // Use the subscribe() method to collect all the elements in a stream Flux<Integer> elementsFlux = Flux.just(1, 2, 3, 4); // subscribe with a subscriber that will print the values, The data will not start flowing until we subscribe elementsFlux().subscribe(System.out::println(i)); Logs: [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | request(unbounded) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(1) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(2) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(3) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onNext(4) 20:25:19.553 [main] INFO reactor.Flux.Array.1 - | onComplete() Reactor - Subscribe
  • 20. > Example: Tell upstream to only send 2 elements at a time by using request(). Flux.just(1, 2, 3, 4) .log() .subscribe(new Subscriber<Integer>() { private Subscription s; int onNextAmount; @Override public void onSubscribe(Subscription s) { this.s = s; s.request(2); } … Reactor – Back Pressure Example (1 of 3)
  • 21. > … @Override public void onNext(Integer integer) { elements.add(integer); onNextAmount++; if (onNextAmount % 2 == 0) { s.request(2); } } @Override public void onError(Throwable t) {} @Override public void onComplete() {} }); Reactor – Back Pressure Example (2 of 3)
  • 22. > Logs: 23:31:15.395 [main] INFO reactor.Flux.Array.1 - | onSubscribe([Synchronous Fuseable] FluxArray.ArraySubscription) 23:31:15.397 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.397 [main] INFO reactor.Flux.Array.1 - | onNext(1) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(3) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onNext(4) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | request(2) 23:31:15.398 [main] INFO reactor.Flux.Array.1 - | onComplete() Notice: The request(2) is called (when Subscribing), followed by two onNext() calls, then request(2) again, then on Complete(). Reactor – Back Pressure Example (3 of 3)
  • 23. > Reactive Operators applies a wide range of transformations to the sequence of data (e.g. Map, Flatmap, Filter, Concat, Merge, buffer, split, transform, delay …) Special diagrams called Marble Diagrams efficiently explains what an operator does, for example: Reactor - Reactive Operators
  • 24. > Map: Transform every item of the emitted sequence with a specified function. Reactor – Reactive Operators Map()
  • 25. > Concat: concatenates 2 or more emissions, generating one emission where all the items from the 1st source emission appear before the items of the 2nd source emission. Reactor - Reactive Operators Concat()
  • 26. > flatMap(): performs 2 types of actions: 1. the “map” action that transforms the emitted item into Flux 2. The “flatten” action that converts those Flux into one Flux. Reactor - Reactive Operators flatMap
  • 27. > Merge: When we want to get feeds from multiple sources as one stream. Reactor - Reactive Operators merge()
  • 28. > Zip: takes multiple observables as inputs and combines each emission via a specified function and emits the results of this function as a new sequence. Reactor - Reactive Operators zip()
  • 29. > StepVerifier API: • Builder API allowing to test how a Flux or Mono behave when subscribed to. Some methods: • expectNext() • expectError() • expectErrorMessage() • expectComplete() • Verify(), VerifyComplete(), VerifyError(), VerifyErrorMessage() Reactor - Testing StepVerifier
  • 30. > Example: // empty Flux Flux<String> emptyFlux = Flux.empty(); StepVerifier.create(emptyFlux).verifyComplete(); // non-empty Flux Flux<String> nonEmptyFlux = Flux.just("John", "Mike", "Sarah"); StepVerifier.create(nonEmptyFlux).expectNext("John", "Mike", "Sarah").verify(); Call to verify(): • triggers the verification by subscribing to the Flux/Mono under test. • Plays the sequence, comparing each new signal with the next step in the scenario • As long as these match, the test is considered a success, else, an AssertionError is thrown. Reactor - Testing StepVerifier
  • 31. > • New spring-webflux module to support reactive HTTP client-side and server-side. • Uses Reactor internally for its own reactive support. Spring Framework 5 Reactive Support
  • 32. > Spring 5 Reactive and Servlet Stack
  • 33. > Add Dependency to pom.xml: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> Spring 5 WebFlux
  • 34. > • Supports 2 distinct programming models: • Annotation-based with @Controller and the other annotations of Spring MVC • Functional Style routing and handling with Java 8 lambda. Spring 5 Server Side
  • 35. > Example: @RestController @RequestMapping(value="/api/customer") public class RestControllerAPIs { @GetMapping("/") public Flux<Customer> getAll() { ... } @GetMapping("/{id}") public Mono<Customer> getCustomer(@PathVariable Long id) { ... } } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 36. > Get all customers test case: Map<Long, Customer> custStores = new HashMap<Long, Customer>(); … @GetMapping public Flux<Customer> getAll() { return Flux.fromIterable(custStores.entrySet().stream() .map(entry -> entry.getValue()) .collect(Collectors.toList())); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 37. > Get a customer test case: @GetMapping("/{id}") public Mono<Customer> getCustomer(@PathVariable Long id) { return Mono.justOrEmpty(custStores.get(id)); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 38. > Create a customer test case: @PostMapping("/post") public Mono<ResponseEntity<String>> postCustomer(@RequestBody Customer customer) { // do post custStores.put(customer.getCustId(), customer); return Mono.just(new ResponseEntity<>("Post Successfully!", HttpStatus.CREATED)); } Spring 5 - WebFlux Server Side - Annotation-based - Example
  • 39. > Framework introduces 2 fundamental components: • Routes a given HTTP requests via a RouterFunction (alternative to using annotations like @RequestMapping) • Handles the request via HandlerFunction (alternative to @Controller’s handler methods). RouterFunction utility classes are used to create RouterFunction: e.g. RouterFunction.route(RequestPredicate, HandlerFunction): • helper function to create routes. • Allows to route requests by applying a RequestPredicate. • When the predicate is matched, then the second argument is run. Spring 5 - WebFlux Server Side - Functional Style
  • 40. > Example: RouterFunction router = route( GET("/test"), request -> ok().build() ) ; • GET("/test") is the RequestPredicate. • req -> ok().build() is the handler producing the response. Spring 5 Server Side – Functional Style
  • 41. > WebClient • Is a reactive client for performing HTTP requests with Reactive Streams back pressure. • Is replacing the classic RestTemplate. • Is an interface which has a single implementation – DefaultWebClient class. Usage(similar to HttpClient): 1. Create an instance 2. Make a request 3. Handle the reponse Spring 5 Client side
  • 42. > Create WebClient using one of the 3 options : • With default settings: • WebClient client1 = WebClient.create(); • With a given base URI: • WebClient client2 = WebClient.create("http://localhost:8080 (http://localhost:8080)"); • Using the DefaultWebClientBuilder class: • WebClient client3 = WebClient .builder() .baseUrl("http://localhost:8080 (http://localhost:8080)") .defaultCookie("cookieKey", "cookieValue") .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080 (http://localhost:8080)")) .build(); Spring 5 Client side - WebClient
  • 43. > // Setting a request body //where a Publisher is a reactive component that is in charge of providing a potentially unbounded number of sequenced elements. WebClient.RequestHeadersSpec requestSpec1 = WebClient.create() .method(HttpMethod.POST) .uri("/resource") .body(BodyInserters.fromPublisher(Mono.just("data")), String.class); WebClient.RequestHeadersSpec<?> requestSpec2 = WebClient.create("http://localhost:8080 (http://localhost:8080)") .post() .uri(URI.create("/resource")) .body(BodyInserters.fromObject("data")); Spring 5 Client side - WebClient
  • 44. > A Response is obtained with exchange() or retrieve(): • exchange(): provides a ClientResponse along with its status, headers • retrieve(): fetches a body directly Example: String response2 = request1.exchange() .block() .bodyToMono(String.class) .block(); String response3 = request2.retrieve() .bodyToMono(String.class) .block(); Note: The block method on Monos is used to subscribe and retrieve an actual data which was sent with the response. Spring 5 Client side - WebClient
  • 45. > WebTestClient • is a non-blocking, reactive client for Spring-webflux integration testing support. • Offers an identical API as the WebClient. • can connect to any server over an HTTP connection. • provides a fluent API to verify responses. • can also bind directly to WebFlux applications with mock request and response objects. Spring 5 Spring WebFlux Testing
  • 47. > @WebFluxTest: • auto-configures WebTestClient to quickly test WebFlux controllers without starting a full HTTP server Example of an unit test: @RunWith(SpringRunner.class) @WebFluxTest public class SpringWebFluxTestApplicationTests { @Autowired private WebTestClient webTestClient; … } Spring 5 - WebFlux Testing
  • 48. > Test without starting an actual server: WebTestClient client = WebTestClient.bindToRouterFunction(routingFunction()) .build(); client.get().uri("/").exchange() .expectStatus().isOk(); // Assert Test with a real server: WebTestClient client = WebTestClient.bindToServer() .baseUrl("http://localhost:8080 (http://localhost:8080)") .build(); client.get().uri("/").exchange() .expectStatus().isOk(); // Assert Spring 5 - WebFlux WebTestClient
  • 49. > Get test case: Using WebTestClient API: webTestClient.get().uri("/api/customer/{id}", 2).accept(MediaType.APPLICATION_JSON).exchange() .expectStatus().isOk().expectBody(Customer.class).isEqualTo(customerMap.get("Peter")); // Assert Using RouterFunction: // The Router Function RouterFunction myRouterFunction = route(GET("/test"), // RouterFunction request -> ok().body(fromObject("hello world"))); // HandlerFunction // Register the RouterFunction WebTestClient webTestClient = WebTestClient.bindToRouterFunction(myRouterFunction).build(); // Assert the response webTestClient.get().uri("/test").exchange().expectStatus().isOk(); Spring 5 WebTestClient - Example
  • 50. > POST test case: webTestClient // Create a POST request .post() .uri("/api/customer/post") .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromObject(customerMap.get("Mary"))) .exchange() // Assert the response .expectStatus().isCreated() .expectBody(String.class) .isEqualTo("Post Successfully!"); Spring 5 WebTestClient - Example
  • 51. > PUT test case: webTestClient // Create a PUT request .put().uri("/api/customer/put/{id}", 3) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromObject(customerMap.get("Amy"))) .exchange() // Assert the response .expectStatus().isCreated() .expectBody(Customer.class) isEqualTo(customerMap.get("Amy")); Spring 5 WebTestClient - Example
  • 52. > DELETE test case: webTestClient // Create a DELETE request .delete().uri("/api/customer/delete/{id}", 1) .exchange() // Assert the response .expectStatus().isAccepted() .expectBody(String.class) .isEqualTo("Delete Succesfully!"); Spring 5 WebTestClient - Example
  • 53. > Spring WebFlux is supported on the following servers: • Netty • Undertow • Tomcat • Jetty • Servlet 3.1+ containers Spring Boot 2 uses Netty by default with WebFlux Spring 5 Choosing a server
  • 54. > • Asynchronous • Non Blocking • Event Driven • Data as stream Reactive Data Access
  • 55. > Spring Data support Reactive Streams Reactive Spring Data Modules: • MongoDb • Redis • Cassandra • CouchDB Reactive Spring Data
  • 56. > Lets see an example based on Spring Data and MongoDB Spring Data - MongoDB
  • 57. > Getting up a running Reactive Streams with Spring Data and MongoDB: • Add the dependency (in pom.xml) • Configuration (@EnableReactiveMongoRepositories) • Repository interface (extends ReactiveMongoRepository, and use Flux and Mono types) Spring Data - MongoDB
  • 58. > Add Reactive MongoDB to our pom.xml: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency> </dependencies> <repositories> <repository> <id>spring-libs-snapshot</id> <name>Spring Snapshot Repository</name> <url>http://repo.spring.io/libs-snapshot</url> </repository> </repositories> Spring Data - MongoDB Example
  • 59. > @Configuration @EnableReactiveMongoRepositories(basePackageClasses = PersonRepository.class) public class MongoConfig extends AbstractReactiveMongoConfiguration { @Bean public MongoClient mongoClient() { return MongoClients.create(); } @Override protected String getDatabaseName() { return "test"; } @Bean public ReactiveMongoTemplate reactiveMongoTemplate() { return new ReactiveMongoTemplate(mongoClient(), getDatabaseName()); } } Spring Data – MongoDB Example - Configuration
  • 60. > Configuration: @EnableMongoRepositories enable the use of ReactiveCrudRepository. For example: • Mono<S> = save(S entity) • Mono<T> = findById(ID id) • Mono<T> = findById(Publisher<ID> id) • Uses the first emitted element to perform the find-query • Mono<void> = deleteById(ID id) • Mono signaling when operation is completed Spring Data – MongoDB Example
  • 61. > Repository: @EnableMongoRepositories enable the use of ReactiveCrudRepository. public interface PersonRepository extends ReactiveMongoRepository<Person, String> { Flux<Person> findByFirstName(final String firstName); Mono<Person> findOneByFirstName(final String firstName); Mono<void> = deleteById(ID id); //Mono signaling when operation is completed } Notice: • Flux<Person> replaces the use of List • Mono<Person> is used instead of Person. This allows to perform functions on each element as they come from MongoDB database, instead of waiting until all records are returned, and then do something with them. Spring Data – MongoD Example
  • 62. > Application: @SpringBootApplication public class Application implements CommandLineRunner { … @Override public void run(String args[]) { final Person johnAoe = new Person("john", "aoe", LocalDateTime.now(), "loser", 0); final Person johnBoe = new Person("john", "boe", LocalDateTime.now(), "a bit of a lose personRepository.saveAll(Flux.just(johnAoe, johnBoe)).subscribe(); personRepository.findByFirstName("john").log().map(Person::getSecondName) .subscribe(System.out::println); personRepository.findOneByFirstName("john").log().map(Person::getId) .subscribe(System.out::println); } } Spring Data – MongoD Example
  • 63. > Associated Logs: 2017-07-16 16:44:09.201 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : onSubscribe(FluxOnErrorResume.ResumeSubscriber) 2017-07-16 16:44:09.208 INFO 13476 --- [ main] reactor.Flux.OnErrorResume.1 : request(unbounded) 2017-07-16 16:44:09.242 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0)) aoe 2017-07-16 16:44:09.243 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onNext(Person(firstName=john, secondName=boe, profession=a bit of a loser, salary=10)) boe 2017-07-16 16:44:09.247 INFO 13476 --- [ Thread-4] reactor.Flux.OnErrorResume.1 : onComplete() 2017-07-16 16:44:09.254 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : onSubscribe(FluxOnErrorResume.ResumeSubscriber) 2017-07-16 16:44:09.255 INFO 13476 --- [ main] reactor.Mono.OnErrorResume.2 : request(unbounded) 2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onNext(Person(firstName=john, secondName=aoe, profession=loser, salary=0)) 596b89c97ab38934a404a80c 2017-07-16 16:44:09.260 INFO 13476 --- [ Thread-4] reactor.Mono.OnErrorResume.2 : onComplete() Spring Data – MongoD Example
  • 64. > • The Reactive Manifesto: • https://www.reactivemanifesto.org/ • Reactor: • https://projectreactor.io/ • Spring WebFlux: • https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html • Going reactive with Spring Data: • https://spring.io/blog/2016/11/28/going-reactive-with-spring-data • Servlet vs Reactive Stacks in Five Use Cases: • https://www.infoq.com/presentations/servlet-reactive-stack References