타입 안전한 요청
필수 종속성: 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
아티팩트를 포함해야 합니다:
Ktor 클라이언트에 필요한 아티팩트에 대한 자세한 내용은
Resources 설치
Resources
을(를) 설치하려면 클라이언트 구성 블록 내에서 install
함수에 전달하세요:
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
클래스를 정의하는 방법을 보여줍니다.
import io.ktor.resources.*
@Resource("/articles")
class Articles()
쿼리 매개변수를 사용하는 리소스
아래 Articles
클래스에는 쿼리 매개변수 역할을 하는 sort
문자열 속성이 있으며, 이는 sort
쿼리 매개변수를 사용하여 다음 경로에 응답하는 리소스를 정의할 수 있게 합니다: /articles?sort=new
.
@Resource("/articles")
class Articles(val sort: String? = "new")
중첩 클래스를 사용하는 리소스
여러 경로 세그먼트를 포함하는 리소스를 생성하기 위해 클래스를 중첩할 수 있습니다. 이 경우 중첩 클래스는 외부 클래스 유형의 속성을 가져야 합니다. 아래 예시는 /articles/new
경로에 응답하는 리소스를 보여줍니다.
@Resource("/articles")
class Articles() {
@Resource("new")
class New(val parent: Articles = Articles())
}
경로 매개변수를 사용하는 리소스
아래 예시는 경로 세그먼트와 일치하고 id
라는 이름의 매개변수로 캡처하는 중첩된 {id}
정수 경로 매개변수를 추가하는 방법을 보여줍니다.
@Resource("/articles")
class Articles() {
@Resource("{id}")
class Id(val parent: Articles = Articles(), val id: Long)
}
예를 들어, 이 리소스는 /articles/12
에 응답하는 데 사용될 수 있습니다.
예시: CRUD 작업을 위한 리소스
위의 예시들을 요약하고 CRUD 작업을 위한 Articles
리소스를 생성해 봅시다.
@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
경로에 요청을 만드는 방법을 보여줍니다.
@Resource("/articles")
class Articles()
fun main() {
runBlocking {
val client = HttpClient(CIO) {
install(Resources)
// ...
}
val getAllArticles = client.get(Articles())
}
}
아래 예시는 예시: CRUD 작업을 위한 리소스에서 생성된 Articles
리소스에 타입 지정된 요청을 만드는 방법을 보여줍니다.
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.