카테고리 없음

Ktor Type-safe requests

hik14 2022. 7. 19. 17:53

Ktor는 Type safe requests 을 구현할 수 있는  resource 플러그인을 제공.

 

서버에서 사용 가능한 리소스를 설명하는 클래스를 만든 다음 @Resource 키워드를 사용하여 이 클래스에 주석을 달아야 합니다.

이러한 클래스에는 kotlinx.serialization 라이브러리에서 제공하는 @Serializable 주석도 있어야 합니다.

 

의존성,

kotlinx.serialization 추가

Gradle

implementation("io.ktor:ktor-client-resources:$ktor_version")

Install Resources

 클라이언트 구성 블록 내부의 설치 함수에 리소스를 전달

val client = HttpClient(CIO) {
    install(Resources)
}

Resource URL

/articles 경로에 응답하는 리소스를 지정하는 Articles 클래스를 정의하는 방법.

import io.ktor.resources.*

@Serializable
@Resource("/articles")
class Articles()

Resources with a query parameter

Articles 클래스에는 쿼리 매개변수 역할을 하는 sort 문자열 속성이 있으며,

이를 통해 sort query parameter를 사용하여 /articles?sort=new. 경로에 응답하는 리소스를 정의

@Serializable
@Resource("/articles")
class Articles(val sort: String? = "new")

Resources with nested classes

path 세그먼트를 포함하는 리소스를 생성하기 위해 클래스를 중첩할 수 있습니다. 

nested 클래스에는 외부 클래스 유형의 속성이 있어야 합니다. 

 

/articles/new 경로에 응답하는 리소스

@Serializable
@Resource("/articles")
class Articles() {
    @Serializable
    @Resource("new")
    class New(val parent: Articles = Articles())
}

Resources with a path parameter

아래 예는 경로 세그먼트와 일치하는 중첩된 {id} 정수 path parameter 를 추가하고 이를 id라는 매개변수로 캡처하는 방법을 보여줍니다.

@Serializable
@Resource("/articles")
class Articles() {
    @Serializable
    @Resource("{id}")
    class Id(val parent: Articles = Articles(), val id: Long)
}

 A resource for CRUD operations

/articles 

/articles/new 

/articles/{id}

/articles/{id}/edit

@Serializable
@Resource("/articles")
class Articles() {
    @Serializable
    @Resource("new")
    class New(val parent: Articles = Articles())

    @Serializable
    @Resource("{id}")
    class Id(val parent: Articles = Articles(), val id: Long) {
        @Serializable
        @Resource("edit")
        class Edit(val parent: Id)
    }
}

Make type-safe requests

fun main() {
    runBlocking {
        val client = HttpClient(CIO) {
            install(Resources)
            defaultRequest {
                host = "0.0.0.0"
                port = 8080
                url { protocol = URLProtocol.HTTP }
            }
        }

        val getAllArticles = client.get(Articles())
        val newArticle = client.get(Articles.New())
        val postArticle = client.post(Articles()) { setBody("Article content") }
        val getArticle = client.get(Articles.Id(id = 12))
        val editArticlePage = client.get(Articles.Id.Edit(Articles.Id(id = 12)))
        val putArticle = client.put(Articles.Id(id = 12)) { setBody("New article content") }
        val deleteArticle = client.delete(Articles.Id(id = 12))
}