类型安全的请求
所需依赖项: io.ktor:ktor-client-resources
Ktor 提供了 Resources
插件,允许您实现类型安全的请求。为此,您需要创建一个类,用于描述服务器上可用资源,然后使用 @Resource
关键字标注该类。请注意,@Resource
注解具有由 kotlinx.serialization 库提供的 @Serializable
行为。
Ktor 服务器提供了实现类型安全的路由的功能。
添加依赖项
添加 kotlinx.serialization
鉴于资源类应具有 @Serializable
行为,您需要按照 Setup 部分所述添加 Kotlin 序列化插件。
添加 Resources 依赖项
要使用 Resources
,您需要将 ktor-client-resources
artifact 包含在构建脚本中:
您可以从
安装 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。