실무 프로젝트로 배우는 Kotlin & Spring/스프링 WebFlux 이해하기

애노테이션 컨트롤러

webmaster 2022. 12. 11. 10:49
728x90

애노테이션 컨트롤러

@RestController //웹 플럭스에서도 동일하게 애노테이션을 사용할 수 있다.
class HelloController {
    @GetMapping
    fun hello() = "Hello WebFlux"
}
  • WebFlux에서 제공하는 애노테이션 컨트롤러 모델은 전통적인 SpringMVC에서 사용하던 애노테이션  기반의 요청, 응답을 그대로 사용할 수 있다.

Book 서비스 개발

Controller

@RestController
class BookController(
    private val bookService: BookService,
) {
    @GetMapping("/books")
    fun getAll(): Flux<Book> { //스프링에서 반환 타입이, Flux,Subscribe 일 경우 알아서 subscribe를 호출해준다.
        return bookService.getAll()
    }

    @GetMapping("/books/{id}")
    fun get(@PathVariable id: Int): Mono<Book> {
        return bookService.get(id)
    }

    @PostMapping("/books")
    fun add(@RequestBody request: Map<String, Any>): Mono<Book> {
        return bookService.add(request)
    }

    @DeleteMapping("/books/{id}")
    fun delete(@PathVariable id: Int): Mono<Void> {
        return bookService.delete(id)
    }
}

Service

@Service
class BookService {
    private final val nextId = AtomicInteger(0)
    val books = mutableListOf(
        Book(id = nextId.incrementAndGet(), name = "코틀린 인 액션", price = 30000),
        Book(id = nextId.incrementAndGet(), name = "HTTP 완벽 가이드", price = 40000),
    )

    fun getAll(): Flux<Book> {
        //return Flux.fromIterable(books)
        return books.toFlux() //코틀린에서는 펙토리 함수가 아닌 확장함수를 통해 flux로 변환을 해주는 함수가 존재한다.
    }

    fun get(id: Int): Mono<Book> {
        return Mono.justOrEmpty(books.find { it.id == id })
    }

    fun add(request: Map<String, Any>): Mono<Book> {
        return Mono.just(request)
            .map { map ->
                val book = Book(
                    id = nextId.incrementAndGet(),
                    name = map["name"].toString(),
                    price = map["price"] as Int
                )
                books.add(book)
                book
            }
    }

    fun delete(id: Int): Mono<Void> {
        return Mono.justOrEmpty(books.find { it.id == id })
            .map { books.remove(it) }
            .then() //then을 통해 mono을 Void로 반환
    }
}
  • Controller의 반환 값이 Mono/Flux 일 경우 WebFlux에서 자동으로 subscribe를 호출해준다(Reactive 프로그래밍에서 Subscribe를 반드시 호출해야 하기 때문)
  • id 같은 경우 하나씩 자동증가를 사용해야 하기 때문에 AutomicInteger를 사용하였다.
  • Kotlin에서는 Flux/Mono로 변경하는 펙토리 메서드뿐만 아니라, 확장 함수로 toFlux, toMono 함수를 제공한다(JAVA는 지원하지 x)
728x90