型別安全請求
必要相依性:io.ktor:ktor-client-resources
程式碼範例: client-type-safe-requests
Ktor 提供 Resources 外掛程式,讓您能夠實作型別安全請求。為此,您需要建立一個描述伺服器可用資源的類別,然後使用 @Resource 關鍵字來註解該類別。請注意,@Resource 註解具有由 kotlinx.serialization 程式庫提供的 @Serializable 行為。
Ktor 伺服器提供了實作型別安全路由的功能。
新增相依性
新增 kotlinx.serialization
鑑於資源類別應具備 @Serializable 行為,您需要按照 Setup 章節中的說明新增 Kotlin 序列化外掛程式。
新增 Resources 相依性
若要使用 Resources,您需要在建置指令碼中包含 ktor-client-resources 構件:
TIP
若要進一步了解 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。
