Spring I/O 2017報告会

2017/6/29 JSUG勉強会

自己紹介

元ネタセッション

Session Speaker
Reactor 3, the reactive foundation for Java 8 (and Spring 5) Simon Baslé
New in Spring 5: Functional Web Framework Arjen Poutsma
Reactive Meets Data Access Christoph Strobl

http://lanyrd.com/2017/spring-io/

お詫び

槙さん講演@Java Day Tokyo 2017
「Spring Framework 5.0によるReactive Web Application」

の激しい劣化版に結果的になってしまったこと
ご了承ください。

agenda

Reactiveとは

本当のリアクティブプログラミングの詳細は、
NTTの岩塚さん、堅田さんのスライド

Reactive Streamsとは

Publisher ---[onNext()]--> Subscriber
          <--[request()]--

MonoとFlux (Reactor)

Flux<String> publisher = Flux.just("aaa", "bbb", "ccc")
        .map(String::toUpperCase).repeat(2);

publisher.subscribe(System.out::print);

// AAABBBCCCAAABBBCCC

Spring5でのReactive

spring-webflux

https://docs.spring.io

Spring5でのReactive

@RestController
public class EchoController {
  @PostMapping("/echo")
  Flux<String> upperCase(@RequestBody Flux<String> body) {
    return body.map(String::toUpperCase);
  }
}

無限ストリームの返却(Server Sent Event)

@GetMapping("/infinite")
Flux<Long> infinite() {
    return Flux.interval(Duration.ofSeconds(1));
}
curl http://... -H "Accept: text/event-stream"
data:0

data:1

data:2
...

agenda

Overview

RouterFunction

RouterFunction<ServerResponse> router = RouterFunctions.route(
                RequestPredicates.GET("/func1"), handler1)
                .andRoute(RequestPredicates.GET("/func2"), handler2);

HandlerFunction

HandlerFunction<ServerResponse> handler = req -> {
    return ServerResponse.ok().body(
            Mono.just(req.queryParam("query").get()),
            String.class);
};

Example

@Bean
RouterFunction<ServerResponse> router() {
    return RouterFunctions.route(POST("/func"),
            req -> ServerResponse.ok().body(
                    req.bodyToFlux(String.class)
                           .map(String::toUpperCase), String.class));
}

HandlerFilterFunction

@Bean
RouterFunction<ServerResponse> routerWithFilter() {
    return RouterFunctions.route(POST("/filter1"),
            req -> ServerResponse.ok().body(
                    req.bodyToFlux(String.class)
                            .map(String::toUpperCase), String.class))
            .andRoute(POST("/filter2"),
                    req -> ServerResponse.ok().body(
                            req.bodyToFlux(String.class), String.class))
            .filter((req, handler) -> {
                System.out.println(req.headers().contentLength());
                return handler.handle(req);
            });
}

Question

agenda

Spring Data 2.0

APIの破壊的変更

Reactive Template API

ReactiveMongoTemplate template;

Flux<Person> flux = template.find(
    new Query(where("_id").is(person.getId())), Person.class);

flux.subscribe(System.out::println);

ReactiveCrudRepository

<S extends T> Mono<S> save(S entity);
<S extends T> Flux<S> saveAll(Publisher<S> entityStream);
Mono<T> findById(ID id);
Flux<T> findAll();
Mono<Long> count();
...

データソース毎のReactive対応状況

Data Source Reactive Support
JPA(JDBC) NG
Redis OK
MongoDB OK
Apache Cassandra OK
Couchbase OK

JPA(JDBC)でのReactiveはなぜNG?

画面レンダリングのReactiveは?

次のセッションにてご紹介!