# Kaxios **Repository Path**: hanxiaohui521/kaxios ## Basic Information - **Project Name**: Kaxios - **Description**: Kotlin版的axios - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-09 - **Last Updated**: 2026-06-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

Kaxios Logo

Kaxios

用 Kotlin 协程复刻 Axios 灵魂的 HTTP 客户端库

Version Kotlin Ktor License SemVer Code of Conduct Security Policy

> **API 稳定性声明**:Kaxios 遵循 [Semantic Versioning 2.0.0](https://semver.org)。主版本号(MAJOR)变更表示不兼容的 API 变更。废弃的 API 会在当前主版本内保持向后兼容至少一个次要版本(MINOR),并在 CHANGELOG 中标注废弃警告。

📖 完整文档 · GitHub · Discord 社区

--- ## 特性 - **协程原生** — 所有 API 都是 `suspend` 函数,完美融入 Kotlin 协程生态 - **类型安全** — `inline reified` 泛型实现零反射反序列化,编译期确定类型 - **管线隔离** — 核心只做请求处理管线,HTTP 发送由 `KaxiosAdapter` 完全隔离,不依赖任何网络库 - **洋葱拦截** — 请求拦截器 FIFO,响应拦截器 FIFO,支持 `onRejected` 错误恢复,内置 100 层深度保护 - **配置优先级** — 全局 < 实例 < 单次请求,Headers/Params 深度合并 - **统一错误** — 所有异常捕获并转为 `KaxiosError`,提供 14 种错误码和辅助属性 - **内置重试** — 指数退避、抖动延时、幂等性检查,支持自定义重试条件 - **丰富类型** — FormData、Blob、StreamResponse、Proxy、连接池配置,XSRF 防护,完整对标 Axios 并增强 - **GraphQL 支持** — 内置 GraphQL 客户端,支持查询、变更和订阅 - **WebSocket 支持** — 基于 Ktor 的 WebSocket 客户端,支持文本、二进制和 JSON 消息 - **SSE 支持** — Server-Sent Events 客户端,支持自动重连、自定义反序列化 - **智能缓存** — 内存缓存适配器,支持多种缓存策略(网络优先、缓存优先等) - **请求去重** — 自动合并重复请求,支持 ETag 和 Last-Modified 条件请求 - **限流控制** — 滑动窗口、固定窗口、令牌桶、漏桶四种限流策略 - **Token 刷新** — 自动 Token 刷新,支持懒加载、急切和预测三种策略 - **日志系统** — 可配置的请求/响应日志,支持文本、JSON 和摘要格式 - **熔断器** — CircuitBreakerAdapter 三态自动恢复,防止雪崩 - **超时控制** — TimeoutAdapter 可组合式超时管理 - **插件化架构** — `KaxiosPlugin` 插件系统,`use()` 安装、`removePlugin()` 卸载,Write Less Do More - **Pipeline DSL** — 链式请求构建器 `pipeline("GET", url).timeout(5000).auth(...).execute()` - **事件驱动** — `KaxiosEventBus` 生命周期事件(请求前/响应后/错误/重试/缓存命中/限流) - **安全增强** — URL 校验、敏感数据脱敏、请求体大小限制 - **渐进迁移** — `KaxiosMigrate` 运行时废弃 API 检测,平滑升级 --- ## 快速开始 ### 1. 环境要求 | 依赖 | 版本 | |------|------| | Kotlin | 2.1.21 | | JVM | 8+ | | Gradle | 8.0+ | | Ktor | 3.1.3 | | kotlinx-coroutines | 1.10.2 | | kotlinx-serialization | 1.8.1 | ### 2. 依赖引入 ```kotlin // build.gradle.kts plugins { kotlin("jvm") version "2.1.21" kotlin("plugin.serialization") version "2.1.21" } repositories { mavenLocal() mavenCentral() } dependencies { implementation("com.github.kaxios:kotlin-axios:3.0.0") } // 或从源码构建 implementation(project(":kotlin-axios")) ``` ### 3. 第一个请求 ```kotlin import com.example.kaxios.* import kotlinx.coroutines.runBlocking @kotlinx.serialization.Serializable data class User(val id: Int, val name: String, val email: String = "") fun main() = runBlocking { val api = Kaxios.create { baseUrl = "https://jsonplaceholder.typicode.com/" timeout = 10000 } // GET - 自动反序列化为 User val user: User = api.get("users/1") println("${user.name} - ${user.email}") // POST - 创建资源 val created: User = api.post("users") { data = User(0, "Bob", "bob@test.com") } println("创建成功: ${created.id}") api.close() } ``` ### 4. 运行项目 ```bash # 克隆项目 git clone https://github.com/kaxios/kotlin-axios.git cd kotlin-axios # 运行测试(串行模式) cd example ./gradlew.bat run # 运行测试(并行模式 - 4并发) ./gradlew.bat run --args="--parallel" # 运行测试(极致并行模式 - 64并发) ./gradlew.bat run --args="--ultra" ``` --- ## 核心类型一览 ### 基础模型 | 类型 | 说明 | |------|------| | `KaxiosConfig` | 30+ 可变配置字段,支持 DSL 构建(`header()`、`param()`、`timeout()` 等) | | `KaxiosRequest` | 不可变请求对象,实现 `ConfigSource` 接口,含方法校验和 `create()` 工厂方法 | | `KaxiosResponse` | 泛型响应对象,包含 `status`、`data`、`headers`、`config` 等字段 | | `KaxiosError` | 统一错误类,12 种错误码,提供 `isTimeout`、`isNetworkError` 等辅助属性 | | `KaxiosHeaders` | 大小写不敏感的 Header 管理器,支持线程安全操作 | ### 高级类型 | 类型 | 说明 | |------|------| | `KaxiosHeadersGroup` | 按 HTTP 方法分组的 Headers(common/get/post/put/patch/delete/head/options) | | `KaxiosAuth` | 认证信息,支持 BASIC/BEARER 两种类型,含 `bearer(token)` 工厂方法 | | `KaxiosProxy` | 代理配置,支持 HTTP/SOCKS 协议 | | `KaxiosFormData` | 线程安全的表单数据,支持字符串/字节字段,可序列化为 JSON | | `KaxiosBlob` | 二进制大对象,支持 `arrayBuffer()`、`text()`、`slice()`、`stream()` | | `StreamResponse` | 流式响应,支持 `readBytes()`、`readText()`、`close()` | | `KaxiosCancelToken` | 取消令牌,基于 `AtomicBoolean` 实现线程安全取消 | | `KaxiosProgressEvent` | 上传/下载进度事件,含 `loaded`、`total`、`progress`、`rate`、`estimated` | | `HttpClientPoolConfig` | 连接池配置:`maxConnections`、`keepAliveTime`、`connectTimeout` 等 | | `RetryConfig` | 重试配置:`maxRetries`、`retryBackoff`、`jitter`、`isIdempotent`、`retryOn` | | `CacheConfig` | 缓存配置:`ttl`、`maxSize`、`strategy`、`filter`、`keyGenerator` | | `DedupConfig` | 去重配置:`enabled`、`cacheEnabled`、`useETag`、`useLastModified` | | `RateLimitConfig` | 限流配置:`maxRequests`、`windowMs`、`strategy`(滑动窗口/固定窗口/令牌桶/漏桶) | | `TokenRefreshConfig` | Token 刷新配置:`refreshToken`、`strategy`(懒加载/急切/预测)、`maxRetries` | | `LogConfig` | 日志配置:`level`、`logHeaders`、`logBody`、`logFormat`(文本/JSON/摘要) | | `GraphQLRequest` | GraphQL 请求:`query`、`variables`、`operationName` | | `GraphQLResponse` | GraphQL 响应:`data`、`errors`、`extensions` | | `KaxiosWebSocket` | WebSocket 客户端接口:`connect()`、`send()`、`close()`、`getEvents()` | | `KaxiosWebSocketEvent` | WebSocket 事件:`Open`、`Message`、`Binary`、`Error`、`Close` | | `KaxiosEventBus` | 事件总线:`beforeRequest`、`afterResponse`、`requestError`、`requestRetry` 等 | | `KaxiosPlugin` | 插件接口:`name`、`version`、`install()` 生命周期 | | `PluginConfig` | 插件配置:`enabled`、`order`、`options` | | `RequestPipeline` | 链式请求构建器:`timeout()`、`auth()`、`header()`、`retry()`、`execute()` | | `ResponsePipeline` | 响应处理链:`onSuccess()`、`onError()`、`onFinally()`、`await()` | | `SecurityValidator` | SSRF 防护:URL 校验、IP 黑白名单、请求体大小限制 | | `SecurityConfig` | 安全配置:`maxUrlLength`、`allowedProtocols`、`maxBodySize` | | `DataMasker` | 敏感数据脱敏:`mask()`、`maskHeader()`、`maskUrl()` | | `DeepMerger` | 深度合并:`mergeMaps()`、`mergeRetryConfig()` 递归合并 | | `KaxiosMigrate` | 渐进迁移:`enabled`、`strictMode`、废弃 API 运行时检测 | ### 管线与工具 | 类型 | 说明 | |------|------| | `Interceptor` | 拦截器接口,含 `onFulfilled` 和 `onRejected` 挂起函数 | | `InterceptorManager` | 拦截器管理器,支持 `add`、`unshift`、`eject`、`removeIf` 等操作 | | `ConfigMerger` | 三级配置合并器,深度合并 Headers/Params,处理 Transform 管线 | | `UrlBuilder` | URL 构建工具,含查询参数编码和 URL 解析 | | `ConfigCopier` | 配置深拷贝工具,支持 `applyTo()` 在 `ConfigSource` 对象间复制 | | `CacheAdapter` | 内存缓存适配器,支持网络优先、缓存优先等多种策略 | | `DedupAdapter` | 请求去重适配器,自动合并重复请求,支持 ETag/Last-Modified | | `RateLimitAdapter` | 限流适配器,支持滑动窗口、固定窗口、令牌桶、漏桶四种策略 | | `TokenRefreshAdapter` | Token 刷新适配器,支持懒加载、急切和预测三种刷新策略 | | `LoggingAdapter` | 日志适配器,支持文本、JSON 和摘要三种日志格式 | | `GraphQLClient` | GraphQL 客户端,支持查询、变更和订阅操作 | | `KaxiosWebSocket` | WebSocket 客户端,支持文本、二进制和 JSON 消息 | | `CaseConverter` | 大小写转换工具,支持 camelCase、snake_case、kebab-case 等 | | `CurlGenerator` | cURL 命令生成器,将请求配置转换为 cURL 命令 | | `SummaryLogger` | 摘要日志格式化器,生成简洁的请求/响应摘要 | | `CloudSigner` | 云服务签名器,支持 AWS、Azure、GCP 等云服务签名 | --- ## 核心功能详解 ### HTTP 方法(全部 `suspend inline reified`) ```kotlin val user: User = api.get("users/1") val users: List = api.get("users") { params["page"] = 1 } val created: User = api.post("users") { data = User(0, "Bob") } val updated: User = api.put("users/1") { data = User(1, "Alice") } val patched: User = api.patch("users/1") { data = mapOf("name" to "Charlie") } api.delete("users/1") val resp: String = api.head("users/1") val options: String = api.options("users/1") ``` ### 拦截器系统 ```kotlin // 请求拦截器 — 添加认证头 api.requestInterceptors.add { req -> req.withHeaders(req.headers + ("Authorization" to "Bearer ${getToken()}")) } // 响应拦截器 — 统一日志 api.responseInterceptors.add { resp -> println("[${resp.status}] ${resp.request.url}") resp } // 错误恢复 — Token 刷新 api.responseInterceptors.add( onFulfilled = { it }, onRejected = { e -> if (e.isClientError && e.response?.status == 401) { val newToken = refreshToken() return@add api.request(e.config.withHeaders(e.config.headers + ("Authorization" to "Bearer $newToken"))) } throw e } ) ``` ### KaxiosHeaders(大小写不敏感的 Header 管理) ```kotlin val headers = KaxiosHeaders() headers["Content-Type"] = "application/json" headers["content-type"] // 返回 "application/json"(大小写不敏感) // 合并 Headers headers.putAll(mapOf("X-Api-Key" to "abc123")) // 遍历 for ((key, value) in headers) { println("$key: $value") } // 便捷方法 headers.contentType = "application/json" headers.authorization = "Bearer token" headers.accept = "application/json" ``` ### 进度回调 ```kotlin val api = Kaxios.create { baseUrl = "https://api.example.com/" } // 上传进度 val resp: User = api.post("upload") { data = fileBytes onUploadProgress = { event -> println("上传进度: ${event.progress?.times(100)}%") println("速度: ${event.rate} bytes/sec") println("预计剩余: ${event.estimated}s") } } // 下载进度 val resp = api.request { url = "large-file.bin" responseType = ResponseType.STREAM onDownloadProgress = { event -> println("下载: ${event.loaded}/${event.total} bytes") } } ``` ### XSRF 防护 ```kotlin val api = Kaxios.create { baseUrl = "https://api.example.com/" xsrfCookieName = "XSRF-TOKEN" xsrfHeaderName = "X-XSRF-TOKEN" } // 自定义 XSRF Token 提供者 class MyXsrfProvider : XSRFTokenProvider { override fun getXsrfToken(cookieName: String): String? { return cookieStore.get(cookieName) } } api.setXSRFTokenProvider(MyXsrfProvider()) ``` ### 错误处理 ```kotlin try { val user = api.get("nonexistent") } catch (e: KaxiosError) { when { e.isTimeout -> println("请求超时: ${e.code}") e.isNetworkError -> println("网络错误: ${e.message}") e.isCanceled -> println("请求已取消: ${e.message}") e.isClientError -> println("客户端错误: ${e.response?.status}") e.isServerError -> println("服务器错误: ${e.response?.status}") } // 12 种错误码 when (e.code) { KaxiosError.ERR_NETWORK -> { /* 网络错误 */ } KaxiosError.ETIMEDOUT -> { /* 通用超时 */ } KaxiosError.ECONNECT_TIMEDOUT -> { /* 连接超时 */ } KaxiosError.ESOCKET_TIMEDOUT -> { /* Socket 超时 */ } KaxiosError.ERR_BAD_REQUEST -> { /* 错误请求 */ } KaxiosError.ERR_BAD_RESPONSE -> { /* 错误响应 */ } KaxiosError.ERR_CANCELED -> { /* 已取消 */ } KaxiosError.ERR_DEPRECATED -> { /* 已弃用 */ } KaxiosError.ERR_NOT_SUPPORT -> { /* 不支持 */ } KaxiosError.ERR_INVALID_URL -> { /* 无效 URL */ } KaxiosError.ERR_FR_TOO_MANY_REDIRECTS -> { /* 重定向过多 */ } KaxiosError.ERR_BAD_OPTION_VALUE -> { /* 错误选项值 */ } } } ``` ### 内置重试 ```kotlin val api = Kaxios.create { baseUrl = "https://api.example.com/" retry = RetryConfig( maxRetries = 3, retryDelay = 1000, retryBackoff = 2.0, // 指数退避倍数 jitter = 0.3, // 30% 抖动 isIdempotent = true, // 仅对幂等方法重试 retryOn = { e -> e.isTimeout || e.isServerError }, onRetry = { error, attempt, maxRetries -> println("重试第 $attempt/$maxRetries 次: ${error.message}") } ) } ``` ### 取消请求 ```kotlin val cancelToken = KaxiosCancelToken.source() api.get("users/1") { signal = cancelToken.signal } // 取消 cancelToken.cancel("用户主动取消") // 检查是否已取消 if (e.isCanceled) { println("请求已被取消: ${e.message}") } // 使用 AbortController(推荐) val controller = Kaxios.abortController() api.get("users/1") { signal = controller.signal } controller.abort("用户取消") ``` ### FormData 上传 ```kotlin val formData = KaxiosFormData() formData.append("name", "document") formData.append("description", "重要文件") formData.append("file", byteArray, "document.pdf") val resp = api.post("upload") { data = formData } // 从 JSON 构建 FormData val json = mapOf("name" to "test", "tags" to listOf("a", "b")) val formData2 = toFormData(json) ``` ### 流式响应 ```kotlin val resp = api.request { url = "large-file.bin" responseType = ResponseType.STREAM } val stream = resp.data as StreamResponse // 读取字节 val bytes: ByteArray = stream.readBytes() // 读取文本 val text: String = stream.readText() // 用完关闭 stream.close() ``` ### 并发请求 ```kotlin // all: 并发执行,等待全部完成 val results = Kaxios.all(listOf( { api.get("users/1") }, { api.get("users/2") }, { api.get("users/3") } )) // race: 并发竞速,返回最快完成的结果,取消其余 val fastest: User = Kaxios.race(listOf( { api.get("users/1") }, { api.get("users/2") } )) // batch: 带并发限制的批量请求 val responses = Kaxios.batch( requests = listOf(config1, config2, config3), maxConcurrent = 4 ) // allSettled: 并发执行,等待全部完成,单个失败不影响其他 val settledResults = Kaxios.allSettled( { api.get("users/1") }, { api.get("users/2") }, { api.get("users/999") } // 此请求失败不影响其他 ) settledResults.forEach { result -> result.onSuccess { println(it) } .onFailure { println("请求失败: $it") } } ``` ### GraphQL 支持 ```kotlin // 创建 GraphQL 客户端 val graphqlClient = graphql("https://api.example.com/graphql") .header("Authorization", "Bearer token") .timeout(30000) .build() // 执行查询 val queryResult = graphqlClient.query( query = """ query GetUser($id: ID!) { user(id: $id) { id name email } } """.trimIndent(), variables = mapOf("id" to "1") ) // 执行变更 val mutationResult = graphqlClient.mutate( mutation = """ mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id name } } """.trimIndent(), variables = mapOf("input" to mapOf("name" to "Bob", "email" to "bob@test.com")) ) // 订阅(需要 SSE 支持) val subscriptionFlow = graphqlClient.subscription( query = """ subscription OnUserCreated { userCreated { id name } } """.trimIndent() ) subscriptionFlow.collect { event -> when (event) { is SseEvent.Message -> println("新用户: ${event.data}") is SseEvent.Error -> println("错误: ${event.error.message}") else -> {} } } ``` ### WebSocket 支持 ```kotlin // 创建 WebSocket 连接(内置自动重连) val ws = api.webSocket("wss://echo.websocket.org") { // 可选配置 protocol("chat") pingInterval(30_000) reconnect { // 自动重连配置(v3.0.0 新增) maxRetries = 5 retryDelay = 1000L maxRetryDelay = 30_000L exponentialBackoff = true } } // 监听事件(含 Reconnecting/Reconnected) val events = ws.getEvents() launch { events.consumeEach { event -> when (event) { is KaxiosWebSocketEvent.Open -> println("连接已建立") is KaxiosWebSocketEvent.Message -> println("收到消息: ${event.text}") is KaxiosWebSocketEvent.Binary -> println("收到二进制数据: ${event.bytes.size} bytes") is KaxiosWebSocketEvent.Error -> println("错误: ${event.exception.message}") is KaxiosWebSocketEvent.Close -> println("连接关闭: ${event.code} ${event.reason}") is KaxiosWebSocketEvent.Reconnecting -> println("重连第 ${event.attempt} 次,等待 ${event.delayMs}ms") is KaxiosWebSocketEvent.Reconnected -> println("重连成功,第 ${event.attempt} 次") } } } // 发送消息 ws.send("Hello WebSocket!") ws.sendJson(mapOf("type" to "message", "content" to "Hello")) // 关闭连接(不会触发自动重连) ws.close(1000, "正常关闭") ``` ### 智能缓存 ```kotlin // 使用缓存适配器 val cacheConfig = CacheConfig( ttl = 60_000, // 缓存 60 秒 maxSize = 100, // 最大 100 条 strategy = CacheStrategy.CACHE_FIRST, // 缓存优先策略 filter = { req -> req.method == "GET" }, // 只缓存 GET 请求 keyGenerator = { req -> "${req.method}:${req.url}" } // 自定义缓存键 ) val cachedApi = KaxiosCore( adapter = CacheAdapter(KtorAdapter(), cacheConfig) ) // 第一次请求会从网络获取 val user1 = cachedApi.get("users/1") // 第二次请求会从缓存获取(如果未过期) val user2 = cachedApi.get("users/1") ``` ### 请求去重 ```kotlin // 使用去重适配器 val dedupConfig = DedupConfig( enabled = true, cacheEnabled = true, // 启用响应缓存 useETag = true, // 使用 ETag 条件请求 useLastModified = true, // 使用 Last-Modified 条件请求 cacheTtlMs = 5000 // 缓存 5 秒 ) val dedupApi = KaxiosCore( adapter = DedupAdapter(KtorAdapter(), dedupConfig) ) // 同时发送多个相同请求,只会实际发送一个 coroutineScope { repeat(10) { launch { val user = dedupApi.get("users/1") // 所有请求都会收到相同的响应 } } } ``` ### 限流控制 ```kotlin // 使用限流适配器 val rateLimitConfig = RateLimitConfig( maxRequests = 100, // 每个窗口最多 100 个请求 windowMs = 60_000, // 60 秒窗口 strategy = RateLimitStrategy.SLIDING_WINDOW, // 滑动窗口策略 waitForToken = true, // 如果超限则等待而不是抛出错误 onRateLimited = { req -> println("请求被限流: ${req.url}") } ) val rateLimitedApi = KaxiosCore( adapter = RateLimitAdapter(KtorAdapter(), rateLimitConfig) ) // 自动限流,不会超过配置的速率 repeat(200) { rateLimitedApi.get("users/${it % 10}") } ``` ### Token 自动刷新 ```kotlin // 使用 Token 刷新适配器 val refreshConfig = TokenRefreshConfig( refreshToken = { // 调用刷新 Token 的 API val response = refreshTokenApi.post("auth/refresh") { data = mapOf("refreshToken" to currentRefreshToken) } response.accessToken }, strategy = RefreshStrategy.EAGER, // 急切策略:在过期前主动刷新 tokenLifetimeMs = 3600_000, // Token 有效期 1 小时 expiryThresholdMs = 300_000, // 过期前 5 分钟刷新 applyToken = { req, token -> req.withHeaders(req.headers + ("Authorization" to "Bearer $token")) } ) val authApi = KaxiosCore( adapter = TokenRefreshAdapter(KtorAdapter(), refreshConfig) ) // Token 会自动刷新,无需手动管理 val user = authApi.get("users/1") ``` ### 日志系统 ```kotlin // 使用日志适配器 val logConfig = LogConfig( enabled = true, level = LogLevel.INFO, logHeaders = true, // 记录请求头 logBody = false, // 不记录请求体(可能包含敏感信息) logFormat = LogFormat.SUMMARY, // 使用摘要格式 sensitiveHeaders = setOf("authorization", "cookie") // 敏感头信息 ) val loggedApi = KaxiosCore( adapter = LoggingAdapter(KtorAdapter(), logConfig) ) // 自动记录请求和响应日志 loggedApi.get("users/1") // 输出: [KAXIOS] GET /users/1 -> 200 OK (123ms, 456 bytes) ``` --- ## 内部实现:请求执行管线 ### 完整数据流图 ``` 用户代码 │ ▼ KaxiosCore.request() │ ├─ 1. 构建 KaxiosConfig(DSL) ├─ 2. ConfigMerger.merge(defaults, instance, request) │ └─ 深度合并 Headers/Params/Transform ├─ 3. KaxiosRequest.create(config) ├─ 4. 请求拦截器链(FIFO) │ ├─ Interceptor1.onFulfilled() │ ├─ Interceptor2.onFulfilled() │ └─ InterceptorN.onFulfilled() ├─ 5. executeWithRetry() 包装 │ └─ 指数退避 + 抖动 + 幂等性检查 ├─ 6. Adapter.dispatch(request) │ ├─ preflightCheck() │ ├─ applyConfig() → 构建 Ktor 请求 │ ├─ 重定向循环 │ ├─ validateAndWrap() │ └─ readResponseBody() ├─ 7. 响应拦截器链(FIFO) │ ├─ Interceptor1.onFulfilled() │ ├─ Interceptor2.onFulfilled() │ └─ InterceptorN.onFulfilled() └─ 8. 返回 KaxiosResponse ``` --- ## 架构 ``` ┌──────────────────────────────────────────────────────────────┐ │ Kaxios / KaxiosCore │ │ │ │ ┌────────────────┐ ┌────────────────┐ │ │ │ 请求拦截器链 │ │ 响应拦截器链 │ │ │ │ (FIFO 执行) │ │ (FIFO 执行) │ │ │ │ ├─ Interceptor │ │ ├─ Interceptor │ │ │ │ ├─ Interceptor │ │ ├─ Interceptor │ │ │ │ └─ Interceptor │ │ └─ Interceptor │ │ │ └───────┬────────┘ └────────▲────────┘ │ │ │ │ │ │ ┌───────▼────────────────────────────┴────────────────────┐ │ │ │ ConfigMerger │ │ │ │ defaults > instanceConfig > requestConfig │ │ │ │ (深度合并 headers/params, 处理 transform) │ │ │ └────────────────────────┬────────────────────────────────┘ │ │ │ │ │ ┌────────────────────────▼────────────────────────────────┐ │ │ │ KaxiosAdapter 接口 │ │ │ │ suspend fun dispatch(request): response │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ KtorAdapter — facade 默认 (CIO / OkHttp / Java) │ │ │ │ │ │ OkHttpAdapter — 委托 Ktor + OkHttp 引擎 │ │ │ │ │ │ CacheAdapter — 内存缓存适配器 │ │ │ │ │ │ DedupAdapter — 请求去重适配器 │ │ │ │ │ │ RateLimitAdapter — 限流控制适配器 │ │ │ │ │ │ TokenRefreshAdapter — Token 刷新适配器 │ │ │ │ │ │ LoggingAdapter — 日志记录适配器 │ │ │ │ │ │ 自定义 Adapter — 实现 KaxiosAdapter 接口 │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────┘ │ HTTP 请求 ▼ 外部服务器 ``` ### 四层架构 | 层 | 文件 | 行数 | 职责 | |----|------|------|------| | **Models** | `Models.kt` | ~1340 | 所有数据模型(`KaxiosConfig`、`KaxiosRequest`、`KaxiosResponse`、`KaxiosError`、`KaxiosHeaders`、`KaxiosFormData`、`KaxiosBlob`、`StreamResponse`、`RetryConfig`、`KaxiosCancelToken`、`CacheConfig`、`DedupConfig`、`RateLimitConfig`、`TokenRefreshConfig`、`LogConfig` 等 40+ 类型)、全局函数(`spread()`、`toFormData()`、`formToJSON()`)、常量(`VERSION`)、Transform 管线工具 | | **Chain** | `Chain.kt` | ~276 | 拦截器管线(`Interceptor`、`InterceptorChain`、`InterceptorManager`)、三级配置合并器(`ConfigMerger`)、URL 构建工具(`UrlBuilder`) | | **Core** | `Kaxios.kt` | ~596 | 核心 API(`KaxiosCore` open class + `Kaxios` singleton object)、请求执行管线、重试逻辑(`executeWithRetry()`)、并发控制(`all()`/`race()`/`batch()`)、XSRF Header 注入、WebSocket 支持 | | **Adapter** | `Adapter.kt` | ~436 | 网络适配层(`KaxiosAdapter` 接口、`KtorAdapter` Ktor 实现、`OkHttpAdapter` OkHttp 委托)、请求预检、Body 序列化、响应解析、错误映射、重定向处理、GZIP/Deflate 解压 | | **Extensions** | 多个文件 | ~1500+ | 扩展功能:GraphQL 客户端、WebSocket 客户端、缓存适配器、去重适配器、限流适配器、Token 刷新适配器、日志适配器、大小写转换、cURL 生成、摘要日志、云签名、Retrofit 兼容 | | **总计** | — | **~4150+** | — | **依赖方向**: Models → Chain → Kaxios → Adapter(严格单向依赖) --- ## 项目结构 ``` kotlin-axios/ ├── src/main/kotlin/com/example/kaxios/ │ ├── model/ # 数据模型层 │ │ ├── KaxiosAdapter.kt — 适配器接口(dispatch/close) │ │ ├── KaxiosConfig.kt — 30+ 配置字段 + DSL 构建器 │ │ ├── KaxiosRequest.kt — 不可变请求对象 + create() 工厂 │ │ ├── KaxiosResponse.kt — 响应对象 + 类型转换方法 │ │ ├── KaxiosError.kt — 统一错误类,14 种错误码 │ │ ├── KaxiosHeaders.kt — 大小写不敏感 Header 管理器 │ │ ├── KaxiosFormData.kt — 线程安全 FormData │ │ ├── KaxiosBlob.kt — 二进制大对象 │ │ ├── SharedJson.kt — 全局 Json 实例 │ │ ├── JsonUtils.kt — JSON 工具函数 │ │ └── ... — ProxyModels/TransformModels/ReadableChannel 等 │ ├── core/ # 核心管线层 │ │ ├── Kaxios.kt — 请求管线 + 重试逻辑 + HTTP 方法 │ │ ├── KaxiosFacade.kt — 全局单例入口(object Kaxios) │ │ ├── Chain.kt — 拦截器管线(Interceptor/InterceptorChain) │ │ ├── ConfigMerger.kt — 三级优先级合并器 │ │ ├── Pipeline.kt — RequestPipeline/ResponsePipeline DSL │ │ ├── EventBus.kt — 事件总线(beforeRequest/afterResponse 等) │ │ ├── Plugin.kt — 插件系统(KaxiosPlugin、use/removePlugin) │ │ └── Migrate.kt — 渐进迁移框架(KaxiosMigrate) │ ├── adapter/ # 适配器层 │ │ ├── Adapter.kt — KtorAdapter 实现(CIO/OkHttp/Java 引擎) │ │ ├── RetryAdapter.kt — 重试适配器(指数退避/自定义条件) │ │ ├── CircuitBreakerAdapter.kt — 熔断器适配器(三态自动恢复) │ │ ├── TimeoutAdapter.kt — 超时适配器 │ │ ├── CacheAdapter.kt — 内存缓存适配器 │ │ ├── DedupAdapter.kt — 请求去重适配器 │ │ ├── RateLimitAdapter.kt — 限流适配器(四种策略) │ │ ├── TokenRefreshAdapter.kt — Token 自动刷新适配器 │ │ ├── LoggingAdapter.kt — 日志适配器 │ │ ├── PriorityAdapter.kt — 请求优先级适配器 │ │ └── RetrofitAdapter.kt — Retrofit 兼容适配器 │ ├── protocol/ # 协议层 │ │ ├── GraphQL.kt — GraphQL 客户端 │ │ └── WebSocket.kt — WebSocket 客户端(自动重连) │ ├── sse/ # SSE 层 │ │ ├── KtorSseAdapter.kt — SSE 适配器(支持自动重连) │ │ ├── MockSseAdapter.kt — Mock SSE 适配器 │ │ └── SseModels.kt — SSE 数据模型 │ ├── security/ # 安全层 │ │ ├── SecurityValidator.kt — SSRF 防护、URL/IP 校验 │ │ ├── SecurityConfig.kt — 安全配置(白名单/黑名单) │ │ └── DataMasker.kt — 敏感数据脱敏 │ ├── stream/ # 流式响应 │ │ └── StreamResponse.kt — 流式响应处理 │ └── util/ # 工具层 │ ├── CaseConverter.kt — 大小写转换 │ ├── CurlGenerator.kt — cURL 命令生成器 │ ├── CloudSigner.kt — 云服务签名器 │ ├── DeepMerger.kt — 深度合并工具 │ └── SummaryLogger.kt — 摘要日志格式化器 ├── example/src/main/kotlin/ # 测试代码 ├── adapters-okhttp/ # OkHttp 适配器子模块 ├── docs/ # VitePress 文档站 ├── build.gradle.kts └── settings.gradle.kts ``` --- ## 测试统计 | 指标 | 数值 | |------|------| | 测试文件数 | 31 个 | | 测试用例数 | 441+ 个 | | 测试代码行数 | ~17,405 行 | | 测试分类 | 单元测试、集成测试、并发测试、压力测试、边界测试、回归测试 | 测试策略: - **真实 API 测试**:使用 `https://jsonplaceholder.typicode.com/` 等真实 API 进行端到端验证 - **Mock Adapter 测试**:通过自定义 `KaxiosAdapter` 实现进行隔离测试 - **重试矩阵测试**:全面覆盖 `RetryConfig` 的各种组合 - **并发安全测试**:验证多协程并发下的线程安全性 - **边界压力测试**:超大 Header、超长 URL、极限超时等边界场景 --- ## Axios vs Kaxios 对照 | JS Axios | Kaxios | 说明 | |----------|--------|------| | `axios()` | `api.request { }` | 通用请求 | | `axios.get()` | `api.get()` | GET 请求 | | `axios.post()` | `api.post()` | POST 请求 | | `axios.put()` | `api.put()` | PUT 请求 | | `axios.patch()` | `api.patch()` | PATCH 请求 | | `axios.delete()` | `api.delete()` | DELETE 请求 | | `axios.head()` | `api.head()` | HEAD 请求 | | `axios.options()` | `api.options()` | OPTIONS 请求 | | `axios.create()` | `Kaxios.create { }` | DSL 创建实例 | | `axios.all()` | `Kaxios.all()` | 等待全部完成 | | `axios.allSettled()` | `Kaxios.allSettled()` | 容错并发(v3.0.0) | | `axios.race()` | `Kaxios.race()` | 并发竞速 | | `axios.getUri()` | `api.getUri { }` | URI 构建 | | `interceptors.req` | `requestInterceptors` | 请求拦截器 | | `interceptors.res` | `responseInterceptors` | 响应拦截器 | | `CancelToken` | `KaxiosCancelToken` | 取消令牌 | | `AbortController` | `Kaxios.abortController()` | AbortController | | `defaults` | `Kaxios.defaults` | 全局默认配置 | | `transformRequest` | `transformRequest` | 请求转换管线 | | `transformResponse` | `transformResponse` | 响应转换管线 | | `validateStatus` | `validateStatus` | 状态码校验 | | `XSRF/CSRF` | `xsrfCookieName` / `xsrfHeaderName` | XSRF 防护 | | `headers` (普通对象) | `KaxiosHeaders` | 大小写不敏感 Header 管理 | | — | `KaxiosHeadersGroup` | **Kaxios 增强**: 按方法分组的 Headers | | — | `ConfigCopier` | **Kaxios 增强**: 配置深拷贝工具 | | — | `RetryConfig` | **Kaxios 增强**: 内置重试(退避/抖动/幂等) | | — | `KaxiosFormData` | **Kaxios 增强**: 线程安全 FormData | | — | `StreamResponse` | **Kaxios 增强**: 流式响应 | | — | `KaxiosBlob` | **Kaxios 增强**: 二进制大对象 | | — | `HttpClientPoolConfig` | **Kaxios 增强**: 连接池配置 | | — | `KaxiosProgressEvent` | **Kaxios 增强**: 进度事件(含速率/预估) | | — | `KaxiosProxy` | **Kaxios 增强**: HTTP/SOCKS 代理 | | — | `XSRFTokenProvider` | **Kaxios 增强**: 可插拔 XSRF Token 提供者 | | — | `Kaxios.batch()` | **Kaxios 增强**: 带并发限制的批量请求 | | — | `GraphQLClient` | **Kaxios 增强**: GraphQL 客户端(查询/变更/订阅) | | — | `KaxiosWebSocket` | **Kaxios 增强**: WebSocket 客户端 | | — | `CacheAdapter` | **Kaxios 增强**: 智能缓存适配器 | | — | `DedupAdapter` | **Kaxios 增强**: 请求去重适配器 | | — | `RateLimitAdapter` | **Kaxios 增强**: 限流控制适配器 | | — | `TokenRefreshAdapter` | **Kaxios 增强**: Token 自动刷新适配器 | | — | `LoggingAdapter` | **Kaxios 增强**: 日志记录适配器 | | ^ | `KaxiosEventBus` | **Kaxios 增强**: 事件总线(beforeRequest/afterResponse 等)| | — | `KaxiosPlugin` | **Kaxios 增强**: 插件系统(use/removePlugin)| | — | `RequestPipeline` | **Kaxios 增强**: Pipeline DSL 链式请求构建器 | | — | `SecurityValidator` | **Kaxios 增强**: SSRF 防护、URL 校验 | | — | `DataMasker` | **Kaxios 增强**: 敏感数据脱敏 | | — | `DeepMerger` | **Kaxios 增强**: 深度合并工具 | | — | `KaxiosMigrate` | **Kaxios 增强**: 渐进迁移框架 | --- ## 技术栈 | 库 | 版本 | 用途 | |----|------|------| | Kotlin | 2.1.21 | 编程语言 | | JVM | 8+ | 运行时 | | Ktor Client | 3.1.3 | HTTP 客户端引擎 | | Ktor WebSocket | 3.1.3 | WebSocket 支持 | | kotlinx.coroutines | 1.10.2 | 协程支持 | | kotlinx.serialization | 1.8.1 | JSON 序列化 | --- ## API 文档 ### 核心 API | API | 说明 | 文档链接 | |-----|------|----------| | `Kaxios.create { }` | 创建 Kaxios 实例 | [API Reference](docs/api/kaxios-instance.md) | | `KaxiosCore` | 核心请求类 | [API Reference](docs/api/kaxios-instance.md) | | `KaxiosConfig` | 配置类 | [API Reference](docs/api/config.md) | | `KaxiosResponse` | 响应类 | [API Reference](docs/api/response.md) | | `KaxiosError` | 错误类 | [API Reference](docs/api/error.md) | | `InterceptorManager` | 拦截器管理器 | [API Reference](docs/api/interceptors.md) | | `KaxiosHeaders` | Header 管理器 | [API Reference](docs/api/utilities.md) | | `GraphQLClient` | GraphQL 客户端 | [API Reference](docs/api/graphql.md) | | `KaxiosWebSocket` | WebSocket 客户端 | [API Reference](docs/api/websocket.md) | | `KaxiosEventBus` | 事件总线 | [jQuery 文档](docs/examples/jquery-philosophy.md) | | `RequestPipeline` | Pipeline DSL 链式请求 | [jQuery 文档](docs/examples/jquery-philosophy.md) | | `CacheAdapter` | 缓存适配器 | [API Reference](docs/api/cache.md) | | `DedupAdapter` | 去重适配器 | [API Reference](docs/api/dedup.md) | | `RateLimitAdapter` | 限流适配器 | [API Reference](docs/api/rate-limit.md) | | `TokenRefreshAdapter` | Token 刷新适配器 | [API Reference](docs/api/token-refresh.md) | | `LoggingAdapter` | 日志适配器 | [API Reference](docs/api/logging.md) | ### 使用指南 | 主题 | 文档链接 | |------|----------| | 快速开始 | [Guide](docs/guide/getting-started.md) | | 核心概念 | [Guide](docs/guide/concepts.md) | | 配置合并 | [Guide](docs/guide/config-merging.md) | | 拦截器 | [Guide](docs/guide/interceptors.md) | | 错误处理 | [Guide](docs/guide/error-handling.md) | | 取消请求 | [Guide](docs/guide/cancel-request.md) | | 认证 | [Guide](docs/guide/authentication.md) | | 适配器 | [Guide](docs/guide/adapter.md) | | 架构 | [Guide](docs/guide/architecture.md) | | GraphQL | [Guide](docs/guide/graphql.md) | | WebSocket | [Guide](docs/guide/websocket.md) | | 缓存策略 | [Guide](docs/guide/caching.md) | | 限流控制 | [Guide](docs/guide/rate-limiting.md) | | 日志系统 | [Guide](docs/guide/logging.md) | | 请求去重 | [Guide](docs/guide/dedup.md) | | Token 刷新 | [Guide](docs/guide/token-refresh.md) | | jQuery 风格 | [Examples](docs/examples/jquery-philosophy.md) | --- ## 贡献指南 ### 开发流程 1. **Fork 仓库** 2. **创建特性分支** (`git checkout -b feature/amazing-feature`) 3. **提交更改** (`git commit -m 'feat: add amazing feature'`) 4. **推送到分支** (`git push origin feature/amazing-feature`) 5. **创建 Pull Request** ### 代码规范 - 遵循 Kotlin 官方代码风格 - 使用 `inline reified` 泛型,禁止传入 `Class` - 所有对外 API 必须是 `suspend` 函数,禁止 Callback - 禁止抛出原生异常,统一使用 `KaxiosError` - 核心逻辑禁止依赖 OkHttp 等网络库,必须通过 Adapter 层 ### 提交规范 ``` feat: 添加新功能 fix: 修复 bug docs: 更新文档 refactor: 代码重构 test: 添加/修改测试 style: 代码格式调整 chore: 构建/工具相关 ``` --- ## 许可证 MIT License — 详见 [LICENSE](LICENSE) 文件 --- ## 社区 - 📖 [完整文档](https://docs.kaxios.dev) - 🐛 [报告 Bug](https://github.com/kaxios/kotlin-axios/issues) - 💡 [功能请求](https://github.com/kaxios/kotlin-axios/issues) - 💬 [Discord 社区](https://discord.gg/kaxios) --- ⭐ 如果这个项目对你有帮助,请给个 Star!