Ktor — 是一个用于 Kotlin 的异步 HTTP 客户端和服务器框架,支持多平台开发。该库基于 Kotlin 协程构建,可在 JVM、iOS、Android、JS 和 Native 上运行。根据 Ktor 在 GitHub 上的仓库数据,该项目由 JetBrains 团队积极开发。Ktor 提供模块化架构和插件系统,用于灵活配置 HTTP 连接。
要点
Ktor — 是一个用 Kotlin 语言创建 HTTP 客户端和服务器的框架,由 JetBrains 公司开发。与传统库不同,Ktor 从一开始就针对多平台开发而设计,可在 Kotlin 支持的所有平台上运行。
Ktor 使用受 Kodein 和 Express.js 架构启发的中间处理程序方法。每个请求都通过一个处理程序函数管道,这些函数可以修改请求和响应。这提供了基于注解的刚性架构库所不具备的灵活性。
当前版本 Ktor 3.0 包括对 Kotlin 2.0、K2 编译器以及具有改进性能的新 CIO(协程 I/O)引擎的支持。该库在 Apache 2.0 许可下分发,可无限制用于商业用途。
Ktor 的客户端部分完全基于 Kotlin 协程构建,确保高效异步执行请求而不阻塞线程。服务器部分允许创建具有路由、请求处理和 WebSocket 连接的 HTTP 服务器。
Ktor 使用插件化架构:所有附加功能 — 日志记录、序列化、身份验证 — 都通过插件连接。这使得库具有模块化特性,允许只连接必要的组件,从而减小最终应用程序的大小。
得益于所有平台上的统一 API,开发人员无需为 iOS 和 Android 学习不同的 HTTP 客户端。在多平台项目中,网络层的代码完全共享,特定于平台的实现隐藏在 HttpClient 引擎后面。这缩短了开发时间,减少了与平台差异相关的错误数量。
Ktor 提供了一系列功能,使其成为现代 Kotlin 项目(尤其是多平台项目)的有吸引力的选择。
Ktor 可在 JVM、Android、iOS、macOS、Windows、Linux、JavaScript 和 Wasm 上运行。相同的 HTTP 客户端代码在所有平台上无需修改即可运行。这是与绑定到 OkHttp 或 URLSession 的库相比的主要优势。
Kotlin 协程提供自然的异步性,无需回调。每个请求都是一个可挂起函数,可以从任何协程调用。Ktor 支持通过 Flow 进行响应流式传输,这对于长连接和 WebSocket 很方便。
Ktor 插件通过 install 块连接并单独配置。主要插件:用于序列化的 ContentNegotiation、用于日志记录的 Logging、用于身份验证的 Auth 和用于双向通信的 WebSockets。每个插件都可以独立启用或禁用。
Ktor 中的错误处理基于异常。ClientRequestException 类在 4xx 代码时抛出,ServerResponseException 在 5xx 时抛出,IOException 在网络错误时抛出。超时通过 HttpTimeout 插件配置,该插件设置连接、读取和写入的等待时间。对于重试,使用 Retry 插件,配置重试次数和延迟。
Ktor 使用管道架构,每个请求都通过一个处理程序链。客户端创建带有已安装插件的 HttpClient 配置,每个 get 或 post 方法调用按连接顺序通过插件。
HttpClient 对象使用特定于平台的引擎创建:JVM 和 Android 使用 CIO,iOS 和 macOS 使用 Darwin,Android 兼容性使用 OkHttp,浏览器使用 Js。引擎可以显式选择或保留自动选择。每个请求返回包含响应正文、标头和状态的 HttpResponse。
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun fetchUsers(): List<User> {
return client.get("https://api.example.com/users").body()
}
安装 Ktor 通过 Gradle 或 Maven 完成。在多平台项目中,依赖项在每个目标的 sourceSets 中指定。Ktor 通过 Maven Central 分发。
在 build.gradle.kts 中为共享代码添加 ktor-client-core 依赖项,并为特定平台添加引擎。Ktor 版本通过 gradle.properties 中的变量设置。Ktor 3.x 需要 Kotlin 2.0+ 并支持 K2 编译器。
val ktorVersion = "3.0.3"
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
}
对于 iOS,使用 Darwin 引擎,它封装了原生 URLSession。在 Kotlin Multiplatform 中,这可以实现最大性能并与 iOS 系统缓存机制集成。该引擎作为单独的依赖项添加到 iOS sourceSet 中。
Ktor 的一个重要特性 — 通过 ContentNegotiation 支持不同的序列化格式。除了 JSON,该插件还支持 Protobuf、CBOR、XML 和自定义格式。对于序列化,使用 kotlinx.serialization 或 Jackson 库,开发人员可以在不更改请求代码的情况下在它们之间切换。
下面的示例展示了使用 Ktor 客户端的典型场景:基本的 GET 请求、数据发送和使用多平台代码。
一个简单的 GET 请求,自动将响应反序列化为数据类。Ktor 使用带有 kotlinx.serialization 的 ContentNegotiation 插件将 JSON 转换为对象。代码简洁且类型安全。
@Serializable
data class Post(
val id: Int,
val title: String,
val body: String
)
suspend fun getPosts(): List<Post> {
val response = client.get("https://jsonplaceholder.typicode.com/posts")
return response.body()
}
Ktor 中的 POST 请求通过带有 contentType 和 setBody 的 post 方法将数据类作为 JSON 正文发送。ContentNegotiation 插件自动将对象序列化为 JSON 字符串。响应可以同步或异步处理。
suspend fun createPost(): Post {
val newPost = Post(
id = 0,
title = "新帖子",
body = "帖子内容"
)
val response = client.post("https://jsonplaceholder.typicode.com/posts") {
contentType(ContentType.Application.Json)
setBody(newPost)
}
return response.body()
}
Ktor 中的 submitFormWithBinaryData 方法允许以 multipart 格式发送文件和表单。Ktor 自动将数据分割成部分并添加标头。为了跟踪进度,使用 onUpload,它接收发送数据的字节。
suspend fun uploadFile(fileBytes: ByteArray) {
client.submitFormWithBinaryData(
url = "https://api.example.com/upload",
formData = formData {
append("file", fileBytes, Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"photo.png\"")
})
}
)
}
选择 Ktor 还是 Retrofit 取决于项目的架构和多平台需求。Retrofit 仍然是纯 Android 项目的标准,而 Ktor 是 Kotlin Multiplatform 的更好选择。
Ktor 还为 WebSocket 和 SSE(服务器推送事件)提供内置支持,使其适用于实时应用程序。Retrofit 不直接支持 WebSocket — 这需要单独的 OkHttp WebSocket 库。Ktor 也更容易为不同环境配置,这得益于插件系统,每个插件负责一个功能。
Ktor 中的 Auth 插件支持基本身份验证、Bearer 令牌、Digest 和 OAuth2。身份验证的配置是声明性的:开发人员指定提供者、令牌来源和作用域。Ktor 自动向请求添加身份验证标头,并可以在令牌过期时刷新令牌。
如果项目在 iOS 和 Android 上使用带有共享代码的 Kotlin Multiplatform,Ktor 是唯一无需额外层即可在两个平台上工作的选项。Retrofit 与 OkHttp 和 JVM 紧密绑定,使其不适用于 iOS。
对于纯 Android 项目,Retrofit 提供更成熟的 API、更多的转换器和 OkHttp 拦截器。Ktor 在这种情况下也能工作,但其插件生态系统不太广泛。两个库都支持协程并提供可比的性能。
| 标准 | Ktor | Retrofit |
|---|---|---|
| 多平台 | iOS、Android、JVM、JS、Native | 仅 JVM 和 Android |
| HTTP 引擎 | CIO、Darwin、OkHttp、Js | OkHttp |
| 转换器 | kotlinx.serialization、Jackson | Gson、Moshi、Jackson、Protobuf |
| 架构 | 带插件的管道 | 带代码生成的注解 |
| 开发者 | JetBrains | Square |
常见问题
Ktor — JetBrains 推出的基于协程的多平台 HTTP 客户端。Retrofit — Square 推出的基于 OkHttp 的 Android 库。Ktor 可在 iOS、Android、JS 和 Native 上运行,而 Retrofit 仅可在 JVM 上运行。
可以,Ktor 通过使用原生 URLSession 的 Darwin 引擎支持 iOS。这确保了最大性能和与 iOS 系统缓存的正确工作。客户端代码在平台之间保持共享。
Ktor 支持引擎:CIO(JVM/Android)、Darwin(iOS/macOS)、OkHttp(Android)、Js(浏览器)、Jetty、Netty、Tomcat(服务器)。引擎可以显式选择或保留自动默认选择。
支持,Ktor 在客户端和服务器端都内置支持 WebSocket。对于客户端,使用 WebSockets 插件,允许建立双向连接并实时交换消息。
错误通过围绕可挂起调用的 try-catch 处理。Ktor 为 4xx 抛出 ClientRequestException,为 5xx 抛出 ServerResponseException,为网络错误抛出 IOException。建议使用 Result 类型进行统一处理。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。