Reactive Spring 5

30
Reactive Spring 5 Reactive Programming with Spring WebFlux and Spring Data Corneil du Plessis

Transcript of Reactive Spring 5

Reactive Spring 5Reactive Programming with Spring WebFlux and Spring Data

Corneil du Plessis

About Me

• Working as Programmer since 1985

• Smallest to very large systems.

• Cobol, Fortan, Pascal, Algol, C/C++, Java, JavaScript, Groovy, Python, Scala, Kotlin and more.

• Scientific instrumentation, Sports event management, Mining, Banking, Treasury and Insurance.

• Software Architect (with a preference for coding)

A definition

reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of

change

Wikipedia

Reactive Manifesto

• Responsive

• Resilient

• Elastic

• Message Driven

Why reactive programming?

• Handle back-pressure

• Communicate change

• Scalability

• Performance

• Reliability

Reactive Programming Models

• Windows API

• JVM Based• NIO• LMAX Disruptor• Akka Actor Model

• JavaScript• AJAX• Promises• jQuery• Angular• React

• FRP – Functional Reactive Programming• map, reduce, filter• Languages not limited to:

• Scala• Kotlin• Haskell• Elm• Groovy• JavaScript• Java 8

Road to Reactive Spring

• RxJava – 2011-2012 by Netflix

• Project Reactor – 2013 by Pivotal

• Reactive Streams Specification – 2014 collaboration by Netflix, Pivotal, Red Hat, Twitter, Typesafe and more.

• reactor-spring

• Spring 5

Implementing Technologies

HttpHander / WebHander API

• Netty

• Undertow

• Tomcat with Servlet 3.1

• Jetty with Servlet 3.1

Reactive Databases

• MongoDB Reactive Streams Driver

• Reactive Cassandra (RxJava)

• Lettuce (Reactive Streams for Redis)

• Reactive Couchbase.

Reactive Streams specification

• Publisher

• Subscriber

• Subscription

• Processor

Reactive Streams – Sequence Diagrams

Subscribe Publish

Project Reactor

• Implements Reactive Streams specification

• Influenced by RxJava

• Influenced by Java 8 Streams

• Improved Developer Experience

• Mono<T> - 0 or One

• Flux<T> - 0 or More

Project Reactor - Mono

static <T> Mono<T> just(T data);

static <T> Mono<T> fromFuture(CompleteableFuture<? extends T>);

Mono<T> log(String category);

T block();

T block(Duration timeout);

map, flatMap, filter

Project Reactor - Flux

static <T> Flux<T> just(T data);

static <T> Flux<T> just(T … data);

static <T> Flux<T> fromStream(Stream<T> s);

static <T> Flux<T> fromIterable<Iterable<T> i);

Flux<T> log(String category);

static <T> Mono<List<T>> collectList();

Mono<T> next();

Iterable<T> toIterable();

Stream<T> toStream();

map, flatMap, filter, reduce

Reactive Spring WebFlux

• Annotated Controllers

• @Controller or @RestController

• @RequestMapping / @GetMapping / @PostMapping etc.

• Flux instead of Collection

• Functional Endpoints• Router Function

• Handler Function

• HandlerFilter Function

Spring MVC

@RestControllerpublic class HistoryController {

private HistoryInterface locHist;public HistoryController(HistoryInterface locHist) {

this. locHist = locHist;}

@GetMapping(path = "/last30days")public Collection<LocationHistory> find(

@RequestParam("startDate") Date startDate,@RequestParam("endDate") Date endDate) {return locHist.find(startDate, endDate);

}}

Reactive Spring WebFlux

@RestControllerpublic class HistoryController {

private HistoryInterface locHist;public HistoryController(HistoryInterface locHist) {

this. locHist = locHist;}

@GetMapping(path = "/last30days")public Flux<LocationHistory> find(

@RequestParam("startDate") Date startDate,@RequestParam("endDate") Date endDate) {return locHist.find(startDate, endDate);

}}

Reactive Spring WebFlux (Functional Endpoint)

public class HistoryHandler {private HistoryInterface locHist;public History HistoryHandler(

HistoryInterface locHist) {this. locHist = locHist;

}public Mono<ServerResponse> find(ServerRequest request) {

Date startDate = DateUtils.from(request.queryParam("startDate"));Date endDate = DateUtils.from(request.queryParam("endDate"));return ServerResponse.ok()

.contentType(APPLICATION_JSON)

.body(locHist.find(startDate, endDate), LocationHistory.class);}

}

Reactive Spring WebFlux (Functional Endpoint)

@Configuration@EnableWebFluxpublic class HistoryConfiguration {

@Autowireprivate HistoryHandler histHandler;@BeanRouterFunction<ServerResponse> router() {

return route(GET("/last30days").and(accept(APPLICATION_JSON)), histHandler::find);

}}

Spring Data

public interface LocationHistoryRepositoryextends CrudRepository<LocationHistory, String> {

Collection<LocationHistory> findByTimestampBetween(Date s, Date e);

}

Reactive Spring Data

public interface LocationHistoryRepositoryextends ReactiveCrudRepository<LocationHistory, String> {

Flux<LocationHistory> findByTimestampBetween(Date s, Date e);

}

Spring Data JPA

• Spring Data JPA does not have Reactive Support.

• Streams will provide best experience until reactive JDBC and JPA is available.

// Repository methodStream<LocationHistory> findByDateBetween(

Date startDate, Date endDate);// Service methodreturn Flux.fromStream(repository.findByDateBetween(s,e));

Demo

Non-reactive

• Spring Boot 1.5.8

• Spring MVC

• Spring Data MongoDB

Reactive

• Spring Boot 2.0 RC

• Spring WebFlux

• Spring Data Reactive MongoDB

Call timing

Non-reactive

• 0.000 >> controller

• 0.000 >> service

• 0.409 << service

• 0.409 << controller

Reactive

• 0.000 >> controller

• 0.000 >> service

• 0.001 << service

• 0.001 << controller

Synchronous process

Asynchronous process

Network timing

Non-reactive

Type Time

Name lookup 0.004

Connect 0.005

Pre transfer 0.005

Start Transfer 0.419

Total 0.532

Reactive

Type Time

Name lookup 0.004

Connect 0.005

Pre transfer 0.005

Start Transfer 0.385

Total 0.425

More aspects of Reactive Programming

• Error handling

• Back pressure

• Retry

• Timeouts

• Transactions

Thoughts on Reactive Spring

• Pros• Great documentation• Preserves program structure• Safer concurrency• Simpler abstraction than RxJava without sacrificing the power.• Facilitates good practice• Kotlin support in Core

• Cons• Debugging complexity• Could not find any other negative comments

See Also

• ReactiveX• Languages

• RxJava• RxKotlin• RxGroovy• RxClojure• RxSwift• Rx.Net (C#) and more…

• Platforms• RxAndroid• RxCocoa• RxNetty

• Akka & Akka Streams

• Ratpack

• Vert.x

• Play Framework

• Languages• Reactor Scala Extensions• Reactor Kotlin Extensions (now in core)

• Messaging Communication• Reactor Kafka• Reactor RabbitMQ• Reactor Aeron• Reactor Netty

Finally

• Source - https://github.com/corneil/reactive-spring-5

• Slides - https://www.slideshare.net/CorneilduPlessis/reactive-spring-5

• Resources• Project Reactor Site - https://projectreactor.io/

• David Karnok's Blog - http://akarnokd.blogspot.co.za/

Questions?