Slide 1

Slide 1 text

WebFluxでコルーチン 2017-11-22 どこでもKotlin #4 長澤太郎 @ngsw_taro

Slide 2

Slide 2 text

自己紹介 ● 長澤 太郎(たろーって呼んでね) ● @ngsw_taro ● エムスリー株式会社 ● ディズニーが大好き!

Slide 3

Slide 3 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 4

Slide 4 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 5

Slide 5 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 6

Slide 6 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 7

Slide 7 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 8

Slide 8 text

従来のスタイル @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): String { val itemA = demoService.getItemA() val itemB = demoService.getItemB() val itemC = demoService.getItemC(itemA, itemB) return itemC.answer } }

Slide 9

Slide 9 text

WebFlux @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 10

Slide 10 text

WebFlux @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 11

Slide 11 text

@RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 12

Slide 12 text

@RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 13

Slide 13 text

@RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 14

Slide 14 text

@RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = Mono.zip( demoService.getMonoA(), demoService.getMonoB() ) .flatMap { demoService.getMonoC(it.t1, it.t2) } .map { it.answer } } WebFlux // dependencies compile('org.springframework.boot:spring-boot-starter-webflux')

Slide 15

Slide 15 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 16

Slide 16 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 17

Slide 17 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 18

Slide 18 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 19

Slide 19 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 20

Slide 20 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 21

Slide 21 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 22

Slide 22 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 23

Slide 23 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 24

Slide 24 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 25

Slide 25 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 26

Slide 26 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 27

Slide 27 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 28

Slide 28 text

Channelで遊ぶ @RestController class DemoController { private val ch = Channel() @GetMapping("read") fun read() = publish { while(isActive) send(ch.receive()) } @GetMapping("write/{msg}") fun write(@PathVariable msg: String) = mono { ch.send(msg) msg } }

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

ハンドラがサスペンド @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") suspend fun handle():String { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } return c.await().answer } } // dependencies compile 'org.springframework.kotlin:spring-webflux-kotlin-coroutine:0.3.1'

Slide 32

Slide 32 text

ハンドラがサスペンド @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") suspend fun handle():String { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } return c.await().answer } } // dependencies compile 'org.springframework.kotlin:spring-webflux-kotlin-coroutine:0.3.1'

Slide 33

Slide 33 text

Reactorでコルーチン @RestController class DemoController(val demoService: DemoService) { @GetMapping("demo") fun handle(): Mono = mono { val a = async { demoService.getItemA() } val b = async { demoService.getItemB() } val c = async { demoService.getItemC(a.await(), b.await()) } c.await().answer } } // dependencies compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.19.3' compile 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor:0.19.3'

Slide 34

Slide 34 text

まとめ ● WebFluxはノンブロッキングでいいね! ● ReactorはFutureやストリームみたいなやつを簡単に扱うこと ができるよ! ● コルーチンは素直に非同期処理を書き下せていいね!