Ktor logo

Ktor

Building Asynchronous Servers and Clients in Kotlin

Ktor 2.0 现已发布

Read this post in other languages:

我们非常高兴地宣布 Ktor 2.0 现已正式发布。 我们已经在这个版本上工作了大约一年,现在终于可以推出了!

Ktor 2.0 引入了许多新功能,但主要版本的意义是重大变更,它让我们有机会执行一些维护工作并摆脱遗留决策。 尽管存在重大变更,我们也已尽可能降低其影响,并提供了有助于自动迁移的实用工具。 不过,首先来看一下新功能:

Ktor 服务器

简化的可扩展性

我们在构建 Ktor 时始终考虑可扩展性。 Ktor 提供的所有功能均以插件架构构建,“功能”也因此更名为“插件”。 我们遇到的问题是,对于某些人来说,架构模型会难以理解。 在 2.0 中,我们大幅简化了可扩展性 API,使插件更易创建。

看看下面 1.x 的 API 代码

companion object Feature : ApplicationFeature<ApplicationCallPipeline, CustomHeader.Configuration, CustomHeader> {
    override val key = AttributeKey<CustomHeader>("CustomPlugin")
    override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): CustomHeader {
       val configuration = Configuration().apply(configure)

       val feature = CustomHeader(configuration)

       pipeline.intercept(ApplicationCallPipeline.Call) {

            feature.intercept(this)
        }

       return feature
    }
}

到了 2.0 中

val myCustomPlugin = createApplicationPlugin("CustomPlugin") {
    onCall {

    }

    onCallReceive {

    }

    onCallRespond {

    }
}

大多数现有插件都已转换为使用新 API,我们非常确定已覆盖大多数情景。 有关详情,请参见 `CustomHeader` 插件从 API 到 API 的转换,以及插件开发文档

我们在可扩展性方面还有更多计划,包括用于从市场轻松发布和使用插件的工具!

Native 支持

在服务器端,除了 GraalVM(从 1.6 开始就已支持)之外,我们现在还支持 Kotlin/Native,这意味着独立服务器应用程序上有了两种选择。

关于 Kotin/Native 支持,目前仅限于使用 CIO 作为引擎,我们将继续在性能领域推进工作。 我们建议使用新的 Kotlin/Native 内存模型。

其他服务器改进

我们还对 Ktor 服务器进行了一系列较小的改进,包括随机端口支持

fun main() {
    embeddedServer(Netty, port = 0) {
        configureRouting()
    }.start(wait = true)
}

以及改进的测试 API、类型安全路由、XML 序列化、插件的子路由以及 60 多个错误修正和其他功能。 

Ktor 客户端

简化的 API

API 得到进一步简化。在 Ktor 客户端中,我们引入了新的 API 来处理常见 HTTP 请求

val result = client.post("http://127.0.0.1:$port/") {

}
result.bodyAsText()

我们已经摆脱了通用的 post<T>, get<T> 方法。 现在,所有内容都返回一个 `HttpResponse`,可供访问正文(使用 `bodyAsText`、`bodyAsChannel`)以及标题。

重试

我们增加了对重试的内置支持,包括重试之间的时间调整

val client = HttpClient(CIO) {
    install(HttpRequestRetry) {
        maxRetries = 5
        retryIf { request, response ->
            !response.status.isSuccess()
        }
        retryOnExceptionIf { _, cause ->
            cause is NetworkError
        }
        delayMillis { retry ->
            retry * 3000L
        } // retries in 3, 6, 9, etc. seconds
    }
}

内容协商

如果您一直在服务器中使用内容协商,您应该已经很熟悉这一功能了。 本质上,它就是客户端与服务器协商可以请求和提供的不同类型内容的能力。 在此之前,它的协商方面仅适用于服务器。 现在,我们也把它带到了客户端!

val client = HttpClient(CIO) {
    install(ContentNegotiation) {
    }
}

这个插件有效取代了 `JsonFeature`。

其他客户端改进

除了上述内容外,客户端还包括用于身份验证的快捷 API(例如 `basic()` 和 `bearer()` 辅助函数)、请求级别的侦听器、新的指标插件、XML 序列化,以及许多错误修正和其他功能

迁移到 Ktor 2.0

我们在 Ktor 上遇到的一个问题是模块和软件包名称不一致。 有些有前缀 server,有些没有。 有些适用于服务器和客户端,但没有任何前缀。 此外,在一个模块中有多个插件会导致发现变得繁琐。 

主要版本的变更让我们有机会在模块和软件包方面引入一些一致的命名惯例。 未来,仅与服务器有关的东西都将具有 server 前缀。 客户端的东西都将具有 client 前缀。 通用软件包将没有前缀。 此外,插件现在位于它们自己的模块中。 

import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.content.*
import io.ktor.util.*
import io.ktor.utils.io.*

模块名称也是如此

implementation "io.ktor:ktor-server-auth:$ktor_version"
implementation "io.ktor:ktor-server-default-headers:$ktor_version"
implementation "io.ktor:ktor-server-sessions:$ktor_version"
implementation "io.ktor:ktor-server-status-pages:$ktor_version"
implementation "io.ktor:ktor-server-cors:$ktor_version"
implementation "io.ktor:ktor-server-conditional-headers:$ktor_version"

为了帮助迁移,我们不仅提供了映射文档,还随 IntelliJ IDEA 提供了迁移工具,它会尝试自动迁移您的 Ktor 项目(请注意,目前不支持 Kotlin Multiplatform 项目)。 

Kotlin 1.6.20 支持和最新文档

至于最新版 Kotlin,Ktor 2.0 与 1.6.20 兼容。 我们还根据所有变更完善了 Ktor 的文档。 我们也将继续改进 API 文档。 

有关 2.0 中所有内容的完整列表,请查看变更日志。 现在就来创建您的第一个 Ktor 2.0 吧!

 

本博文英文原作者: