Web-Flux with Kotlin Demo

github: https://github.com/zhanzhanqi/web-flux

本文將web-flux demo中的handler模式的使用方式進行了節選,直接將本文中代碼服務複製到ide中就可以執行。至於深層次的reactive的套路及其好處,有了更深的體會後在開文章記錄。

pom依賴

  		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
		</dependency>

目前spring支持reactive的repository只有mongo, redis, Cassandra 暫時不支持基於jdbc的MySQL,因此選用了mongo作爲repository。在本地使用docker的方式安裝mongo可以參考Docker安裝Mongo

Model

@Document
class User {
    @Id
    var id: Long? = null
    var firstName: String = ""
    var lastName: String = ""
    var age: Int = -1
}

Reactive Repository

interface ReactiveUserRepository : ReactiveMongoRepository<User, Long>

鏈接Mongo 配置

spring.data.mongodb.host=localhost
spring.data.mongodb.database=admin
spring.data.mongodb.port=27017
spring.data.mongodb.username=mongoadmin
spring.data.mongodb.password=secret

FunctionHandler

@Component
class UserHandler(private val userRepository: ReactiveUserRepository) {

    fun listUser(request: ServerRequest): Mono<ServerResponse> {
        val users = userRepository.findAll()
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(users, User::class.java)
    }

    fun createUser(request: ServerRequest): Mono<ServerResponse> {
        val user = request.body(BodyExtractors.toMono(User::class.java))
                .flatMap { userRepository.save(it) }
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(user, User::class.java)
    }

    fun getUser(request: ServerRequest): Mono<ServerResponse> {
        val userId = request.pathVariable("id").toLong()
        val notFound = ServerResponse.notFound().build()
        val userMono = userRepository.findById(userId)
        return userMono
                .flatMap {
                    user -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(user))
                }.switchIfEmpty(notFound)
    }
}

Router

@Configuration
class UserRouter(private val handler: UserHandler) {
    @Bean
    fun myRouter() = router {
        accept(MediaType.APPLICATION_JSON).nest {
            GET("router/user/{id}", handler::getUser)
            POST("router/user", handler::createUser)
            GET("router/user",handler::listUser)
        }
    }
}

啓動容器

@SpringBootApplication
class WebFluxApplication
fun main(args: Array<String>) {
	runApplication<WebFluxApplication>(*args)
}

啓動

在這裏插入圖片描述

訪問

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章