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

添加 Resources 依赖项

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

Kotlin
Groovy
XML

您可以从

添加客户端依赖项
了解如何将客户端依赖项添加到现有项目。
了解更多关于 Ktor 客户端所需的 artifacts。

安装 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