すきま風

勉強したことのメモとか

Spring Boot WebFluxでThymeleafを使う

WebFluxのサンプルをネットで探すとAPIの例しか見つからなくて、俺はHTML出力したいんだよ!って思ったので自分で書きました。 Data Drivenは試していない 🤗

Controller

Spring MVC風のやつ。Rendering を返す。Kotlinならsuspend functionにするだけでReactiveになる (はず)

@Controller
@RequestMapping("/foo")
class FooController(
    private val repository: FooRepository,
) {
    @GetMapping("bar")
    suspend fun list(): Rendering {
        val fooFlow =
            repository.findAll()

        return Rendering
            .view("index")
            .modelAttribute("fooPresenter", FooPresenter(fooFlow.toList(mutableListOf())))
            .build()
    }
}

Router

Functional Endpointのやつ。ServerResponseを返す

@Configuration(proxyBeanMethods = false)
class FooRoute {
    @Bean
    fun router(
        repository: FooRepository
    ) = coRouter {
        val handler = FookHandler(repository)
        GET("/foo/bar", handler::list)
    }
}

class FooHandler(
    private val repository: FooRepository
) {
    suspend fun list(req: ServerRequest): ServerResponse {
        val fooFlow = repository.findAll()

        return ok().contentType(MediaType.TEXT_HTML).renderAndAwait(
            "index",
            mapOf("fooPresenter" to FooPresenter(fooFlow.toList(mutableListOf())))
        )
    }

参考

Going Reactive with Spring, Coroutines and Kotlin Flow

Spring I/O 2017: Getting Thymeleaf Ready for Spring 5 and Reactive - Speaker Deck