EitherNet与Retrofit集成教程:快速实现网络请求封装
【免费下载链接】EitherNetA multiplatform, pluggable, and sealed API result type for modeling network API responses.项目地址: https://gitcode.com/gh_mirrors/ei/EitherNet
在Android和Kotlin多平台开发中,网络请求是应用开发的核心环节之一。📱 EitherNet作为一个多平台、可插拔且密封的API结果类型库,专门用于建模网络API响应,与Retrofit的完美集成让网络请求处理变得更加优雅和安全。本文将为您提供完整的EitherNet与Retrofit集成指南,帮助您快速掌握这一强大的网络请求封装方案。
🚀 快速开始:安装与配置
首先,您需要在项目中添加EitherNet的依赖。EitherNet现在支持Kotlin多平台开发,核心API位于common代码中,并通过集成模块实现。
在您的build.gradle.kts文件中添加以下依赖:
dependencies { implementation("com.slack.eithernet:eithernet:<version>") implementation("com.slack.eithernet:eithernet-integration-retrofit:<version>") // 测试工具 testImplementation(testFixtures("com.slack.eithernet:eithernet:<version>")) }核心文件路径:build.gradle.kts 包含了项目的基本配置信息。
🔧 基础集成:创建您的第一个API接口
EitherNet的核心类型是ApiResult<out T, out E>,其中T是成功类型,E是可能的错误类型。这个密封接口让您能够以类型安全的方式处理网络响应,无需异常处理!
让我们创建一个简单的API接口:
interface UserApi { @GET("/users/{id}") suspend fun getUser(@Path("id") userId: String): ApiResult<User, ErrorResponse> @POST("/users") suspend fun createUser(@Body user: User): ApiResult<User, ErrorResponse> }关键文件:ApiResult.kt 定义了核心的ApiResult密封接口。
🏗️ Retrofit配置:添加适配器和转换器
配置Retrofit客户端时,需要添加EitherNet的调用适配器和转换器工厂:
val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(ApiResultConverterFactory) .addCallAdapterFactory(ApiResultCallAdapterFactory) .addConverterFactory(GsonConverterFactory.create()) .build() val userApi = retrofit.create<UserApi>()📊 结果处理:优雅的错误处理
EitherNet的最大优势在于其密封类型的错误处理机制。ApiResult有两个密封子类型:Success和Failure。而Failure又进一步分为四个子类型:
NetworkFailure- 网络连接错误HttpFailure- HTTP 4xx/5xx错误ApiFailure- API业务逻辑错误UnknownFailure- 未知错误
处理响应的代码变得非常清晰:
when (val result = userApi.getUser("123")) { is Success -> { val user = result.value showUserProfile(user) } is Failure -> when (result) { is NetworkFailure -> { showNetworkError(result.error) } is HttpFailure -> { when (result.code) { 404 -> showUserNotFound() 500 -> showServerError() else -> showHttpError(result.code, result.error) } } is ApiFailure -> { showApiError(result.error) } is UnknownFailure -> { showUnknownError(result.error) } } }🎯 高级功能:错误体解码
许多API在HTTP错误响应中返回结构化的错误信息。EitherNet支持通过@DecodeErrorBody注解来解码这些错误体:
interface UserApi { @DecodeErrorBody @GET("/users/{id}") suspend fun getUser(@Path("id") userId: String): ApiResult<User, ErrorResponse> }现在,当收到4xx或5xx响应时,EitherNet会尝试将错误体解码为ErrorResponse类型。
🔄 重试机制:指数退避策略
网络请求失败时重试是常见的需求。EitherNet提供了高度可配置的retryWithExponentialBackoff()函数:
val result = retryWithExponentialBackoff( maxAttempts = 3, // 最大尝试次数 initialDelay = 500.milliseconds, // 初始延迟 delayFactor = 2.0, // 延迟因子 maxDelay = 10.seconds, // 最大延迟 jitterFactor = 0.25, // 抖动因子 onFailure = { failure -> // 可选的回调用于日志记录 logError("Request failed: $failure") } ) { userApi.getUser("123") }🧪 测试支持:EitherNetController
EitherNet提供了强大的测试工具EitherNetController,类似于OkHttp的MockWebServer,可以轻松模拟API响应:
class UserApiTest { private val controller = newEitherNetController<UserApi>() private val userApi = controller.api @Test fun testGetUserSuccess() { // 设置预期的成功响应 controller.enqueue(UserApi::getUser, ApiResult.success(User("123", "John Doe"))) // 执行测试 val result = runBlocking { userApi.getUser("123") } assertTrue(result is Success) assertEquals("John Doe", (result as Success).value.name) } @Test fun testGetUserNotFound() { // 设置预期的HTTP错误 controller.enqueue(UserApi::getUser, ApiResult.httpFailure<User, ErrorResponse>(404)) val result = runBlocking { userApi.getUser("123") } assertTrue(result is HttpFailure) assertEquals(404, (result as HttpFailure).code) } }测试工具文件:test-fixtures/ 包含了测试相关的工具类。
🎨 自定义错误处理:可插拔架构
EitherNet支持可插拔的错误处理架构。如果您的API返回多态响应(例如,成功和错误使用相同的HTTP状态码但不同的数据结构),您可以创建自定义的转换器:
class CustomErrorConverterFactory : Converter.Factory() { override fun responseBodyConverter( type: Type, annotations: Array<out Annotation>, retrofit: Retrofit ): Converter<ResponseBody, *>? { val (errorType, nextAnnotations) = annotations.errorType() ?: return null return CustomResponseBodyConverter(errorType.toType()) } class CustomResponseBodyConverter( private val errorType: Type ) : Converter<ResponseBody, *> { override fun convert(value: ResponseBody): Any { if (value.isErrorType()) { val errorResponse = parseError(value) throw ApiException(errorResponse) } else { return parseSuccess(value) } } } }📱 多平台支持:Kotlin多平台开发
从2.0.0版本开始,EitherNet完全支持Kotlin多平台开发。核心API现在位于common代码中,并通过集成模块为不同平台提供实现。
核心多平台文件结构:
- eithernet/src/commonMain/ - 公共代码
- eithernet/src/jvmMain/ - JVM平台实现
- eithernet/src/jsMain/ - JavaScript平台实现
- eithernet/src/nativeMain/ - Native平台实现
🚦 最佳实践:生产环境建议
- 统一错误处理:创建统一的错误处理扩展函数
- 日志记录:利用
tagsAPI记录请求和响应信息 - 类型安全:始终为API结果指定具体的成功和错误类型
- 测试覆盖:使用
EitherNetController确保API层测试覆盖率
📈 版本兼容性
EitherNet 2.0.0进行了重大架构调整,迁移到了Kotlin多平台。如果您从旧版本升级,请注意:
- 核心API现在位于
common代码中 - Retrofit/OkHttp集成迁移到单独的
eithernet-integration-retrofit工件 - 测试工具迁移到新的
eithernet-test-fixtures工件
版本信息:CHANGELOG.md 包含了详细的版本变更记录。
🎉 总结
EitherNet与Retrofit的集成为Kotlin开发者提供了一个强大、类型安全的网络请求处理方案。通过密封类型和可插拔架构,您可以:
✅ 消除异常处理的复杂性
✅ 获得编译时类型安全
✅ 实现优雅的错误处理流程
✅ 轻松进行单元测试
✅ 支持多平台开发
无论是简单的REST API调用还是复杂的多态响应处理,EitherNet都能让您的网络层代码更加健壮和可维护。立即开始使用EitherNet,让您的网络请求处理变得更加优雅!✨
官方文档:README.md 包含了完整的API参考和使用示例。
【免费下载链接】EitherNetA multiplatform, pluggable, and sealed API result type for modeling network API responses.项目地址: https://gitcode.com/gh_mirrors/ei/EitherNet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考