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 行为,您需要按照 设置 部分所述添加 Kotlin 序列化插件。

添加 Resources 依赖项

要使用 Resources,您需要在构建脚本中包含 ktor-client-resources 工件:

Kotlin
Groovy
XML

TIP

要详细了解 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

发出类型安全请求

要向类型化资源 发出请求,您需要将资源类实例传递给请求函数(requestgetpostput 等)。例如,下面的示例演示了如何向 /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