Skip to content
Client Plugin

타입 안전한 요청

필수 종속성: io.ktor:ktor-client-resources

코드 예시: client-type-safe-requests

Ktor는 타입 안전한 요청을 구현할 수 있는 Resources 플러그인을 제공합니다. 이를 위해 서버에서 사용 가능한 리소스를 설명하는 클래스를 생성한 다음, @Resource 키워드를 사용하여 이 클래스에 어노테이션을 지정해야 합니다. @Resource 어노테이션은 kotlinx.serialization 라이브러리에서 제공하는 @Serializable 동작을 가지고 있다는 점에 유의하세요.

Ktor 서버는 타입 안전한 라우팅을 구현하는 기능을 제공합니다.

종속성 추가

kotlinx.serialization 추가

리소스 클래스@Serializable 동작을 가져야 하므로, 설정(Setup) 섹션에 설명된 대로 Kotlin serialization 플러그인을 추가해야 합니다.

Resources 종속성 추가

Resources을(를) 사용하려면 빌드 스크립트에 ktor-client-resources 아티팩트를 포함해야 합니다:

Kotlin
Groovy
XML

Ktor 클라이언트에 필요한 아티팩트에 대한 자세한 내용은

클라이언트 종속성 추가
기존 프로젝트에 클라이언트 종속성을 추가하는 방법을 알아보세요.
에서 확인할 수 있습니다.

Resources 설치

Resources을(를) 설치하려면 클라이언트 구성 블록 내에서 install 함수에 전달하세요:

kotlin
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.resources.*
//...
val client = HttpClient(CIO) {
    install(Resources)
}

리소스 클래스 생성

각 리소스 클래스에는 @Resource 어노테이션이 있어야 합니다. 아래에서는 단일 경로 세그먼트, 쿼리 및 경로 매개변수 등을 정의하는 몇 가지 리소스 클래스 예시를 살펴보겠습니다.

리소스 URL

아래 예시는 /articles 경로에 응답하는 리소스를 지정하는 Articles 클래스를 정의하는 방법을 보여줍니다.

kotlin
import io.ktor.resources.*

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

쿼리 매개변수를 사용하는 리소스

아래 Articles 클래스에는 쿼리 매개변수 역할을 하는 sort 문자열 속성이 있으며, 이는 sort 쿼리 매개변수를 사용하여 다음 경로에 응답하는 리소스를 정의할 수 있게 합니다: /articles?sort=new.

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

중첩 클래스를 사용하는 리소스

여러 경로 세그먼트를 포함하는 리소스를 생성하기 위해 클래스를 중첩할 수 있습니다. 이 경우 중첩 클래스는 외부 클래스 유형의 속성을 가져야 합니다. 아래 예시는 /articles/new 경로에 응답하는 리소스를 보여줍니다.

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

경로 매개변수를 사용하는 리소스

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

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

예를 들어, 이 리소스는 /articles/12에 응답하는 데 사용될 수 있습니다.

예시: CRUD 작업을 위한 리소스

위의 예시들을 요약하고 CRUD 작업을 위한 Articles 리소스를 생성해 봅시다.

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

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

이 리소스는 모든 게시물을 나열하고, 새 게시물을 게시하고, 편집하는 등에 사용될 수 있습니다. 다음 섹션에서 이 리소스에 타입 안전한 요청을 만드는 방법을 살펴보겠습니다.

전체 예시는 여기에서 찾을 수 있습니다: client-type-safe-requests.

타입 안전한 요청 만들기

타입 지정된 리소스에 요청을 만들려면 리소스 클래스 인스턴스를 요청 함수(request, get, post, put 등)에 전달해야 합니다. 예를 들어, 아래 샘플은 /articles 경로에 요청을 만드는 방법을 보여줍니다.

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

fun main() {
    runBlocking {
        val client = HttpClient(CIO) {
            install(Resources)
            // ...
        }
        val getAllArticles = client.get(Articles())
    }
}

아래 예시는 예시: CRUD 작업을 위한 리소스에서 생성된 Articles 리소스에 타입 지정된 요청을 만드는 방법을 보여줍니다.

kotlin
fun main() {
    defaultServer(Application::module).start()
    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))
}

defaultRequest 함수는 모든 요청에 대한 기본 URL을 지정하는 데 사용됩니다.

전체 예시는 여기에서 찾을 수 있습니다: client-type-safe-requests.