类型安全的请求
所需依赖项: 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。
