본문 바로가기

프로그래밍 언어 노트/JAVA | Kotlin

Kotlin ServerResponse 에 대한 DSL 을 구축해보자!

[Spring Boot] + Kotlin 에서 Route + Beans DSL 을 사용해보자 (tistory.com)

 

[Spring Boot] + Kotlin 에서 Route + Beans DSL 을 사용해보자

전통적인 Spring 의 방식 (MVC) 는 컨트롤러 + 서비스 + 레포를 어노테이션으로 등록하고, Spring 이 Bean으로 등록해서 슈슈슉 뜨는 방식인데, 나도 Spring 쓸때는 이렇게 작성하긴 하는데 개인적으로 선

see-ro-e.tistory.com

일전에 요 Post 에서 Kotlin Spring Boot 에서 Route Dsl 을 사용하는것을 확인했고

 

Kotlin SQL DSL 을 구축해보자! 쓸 수 있는 방법을 전부 동원해봐서! (tistory.com)

 

Kotlin SQL DSL 을 구축해보자! 쓸 수 있는 방법을 전부 동원해봐서!

라이브러리를 설계하는 일은 사실 언어를 설계하는 일이다 (벨 연구소 격언) C# 언어에는 LINQ 라는 문법이 존재한다. SQL의 Query 문과 유사한 문법으로 map/reduce/filter 를 수행 할 수 있으며, ORM (엔티

see-ro-e.tistory.com

그리고 요 Post 에서 Kotlin 에서 DSL 을 구축해보았다.

 

Route Dsl 로 구성하게 되면,

각 핸들러 함수의 Return 값을 ServerResponse 로 주어야 하며, 해당 Class 를 Build하는 법은 다음과 같다.

 ServerResponse.ok()
    .contentType(MediaType.TEXT_PLAIN)
    .header("X-TEST-A", "1234")
    .header("X-TEST-B", "5678")
    .body("Hello, World!")

Fluent API 스타일이길래, 이것도 한번 Kotlin DSL 화 시켜 보았다.

 

Lee-WonJun/response-dsl: Kotlin DSL for Spring ServerResponse (github.com)

 

GitHub - Lee-WonJun/response-dsl: Kotlin DSL for Spring ServerResponse

Kotlin DSL for Spring ServerResponse. Contribute to Lee-WonJun/response-dsl development by creating an account on GitHub.

github.com

// MVC
val response = response {
    status { HttpStatus.OK }
    contentType { MediaType.TEXT_PLAIN }
    headers {
        header { "X-TEST-A" to "1234" }
        header { "X-TEST-B" to "5678" }
    }
    body { "Hello, World!" }
}

val responseHeaderShortCut = response {
    status { HttpStatus.OK }
    contentType { MediaType.TEXT_PLAIN }
    headers {
        +{ "X-TEST-A" to "1234" }
        +{ "X-TEST-B" to "5678" }
    }
    body { "Hello, World!" }
}

// Reactive
val responseWithBodyValue = withContext(CoroutineScope(Dispatchers.Default).coroutineContext) {
    response {
        status { HttpStatus.OK }
        contentType { MediaType.TEXT_PLAIN }
        header { "X-TEST-HEADER" to "TEST-VALUE" }
        bodyValue { "Hello World" }
    }
}

val responseWithBody =  withContext(CoroutineScope(Dispatchers.Default).coroutineContext) {
    response {
        status { HttpStatus.OK }
        contentType { MediaType.TEXT_PLAIN }
        header { "X-TEST-HEADER" to "TEST-VALUE" }
        body {
            flow {
                emit("Hello World")
                emit("Hello World")
            }
        }
    }
}

위와 같이 쓸수있고, MVC 용 ServerResponse 와 Reactive 용 ServerResponse 버전 각각 구현했다.

 

기존에는 Fluent API 에서는 이미 있는 ok(), notFount() 같은 설정에 대한 Short-Cut 형식이 존재했는데

이런 Short Cut 형식은 사용자가 유연하게 정의할 수 있도록 고차함수를 하나 추가했다.

val ok = makeDefaultResponse(HttpStatus.OK)
val ok_json = makeDefaultResponse(HttpStatus.OK, MediaType.APPLICATION_JSON)
val ok_text_x_header = makeDefaultResponse(
    HttpStatus.OK, MediaType.TEXT_PLAIN, mapOf("X-TEST-A" to "1234", "X-TEST-B" to "5678"))

val response = ok_text_x_header {
    body { "Hello, World!" }
}

위처럼, makeDefaultResponse 를 이용하여 Body 를 제외한 값을 default 설정해둘수있다.

그다음에는 DSL 처럼 사용하면 미리 설정한 값이 들어가서 사용할수있음

728x90