protoncore_android/network
dkadrikj 519765b9bd Rename ServerConnectionListener.kt to ApiConnectionListener.kt,
ServerConnectionHandler.kt to ApiConnectionHandler.kt and
ServerConnectionException.kt to ApiConnectionException.kt
2021-11-22 15:01:26 +00:00
..
data Rename ServerConnectionListener.kt to ApiConnectionListener.kt, 2021-11-22 15:01:26 +00:00
domain Rename ServerConnectionListener.kt to ApiConnectionListener.kt, 2021-11-22 15:01:26 +00:00
src/main Initial commit 2020-07-01 13:58:49 +03:00
README.md Expose util-kotlin's Logger to network lib clients 2020-07-08 17:56:05 +02:00
build.gradle.kts Add gues hole support into the network module. 2021-11-22 15:01:26 +00:00

README.md

Modules provides support for using Proton API and offers common networking tools.

Gradle:

implementation "me.proton.core:network:{version}"

ApiManager

To start using API client first creates ApiFactory singleton with ApiClient interface implementation. E.g. with Dagger:

@Singleton @Provides
fun provideApiFactory(apiClient: ApiClient, networkManager: NetworkManager, logger: Logger): ApiFactory =
    ApiFactory(context, baseUrl, apiClient, logger, networkManager)

Now ApiFactory can be used to create per-user instances of ApiManager<Api> that implements client-defined retrofit interface Api. Api is needs to be based on suspending functions, inherit from BaseRetrofitApi and can be composed from multiple interfaces.

interface MyRetrofitApi : BaseRetrofitApi, AuthModuleApi, ... {
    @GET("clientEndpoint1") suspend fun myEndpoint(@Body myBody): MyResponse
    ...
}

Response class needs to be annotated according to kotlinx.serialization.

@Serializable
class MyResponse(@SerialName("FieldA") val fieldA: Int, ...)

Now instances of ApiManager supporting MyRetrofitApi and tied to given UserData can be created with ApiFactory

val apiManager1 = apiFactory.ApiManager(
    user1Data, MyRetrofitApi::class, customErrorHandlers, ...)

API calls wit ApiManager are suspending, return ApiResult<T> (no exceptions should be thrown) and perform error handling logic (like retries, DoH, token refresh, force logout, force upgrade as well as custom handling logic through ApiErrorHandler plugins):

val result: ApiResult<MyResponse> = apiManager1 { myEnpoint(body) }

Please note that { myEnpoint(body) } lambda might be executed multiple times (e.g. with retries) so be aware of the side effects - it might make sense to have additional layer defined between client code and apiManager calls e.g.:

class MyApi(private val api: ApiManager<MyRetrofitApi>) {
    suspend fun myEndpoint(param: MyBody) = api { myEndpoint(param) }
}

NetworkManager

Supports checking and observing network states (with kotlin flow):

val networkManager = NetworkManager(context)
networkManager.networkStatus
myScope.launch { networkManager.observe().collect { newState -> ... } }

Serialization utils

Proton API sends Boolean values as 0/1 integers in response json. In order to support serialization from int to bool IntToBoolSerializer needs to be used explicitly on a given field.

@Serializable
class MyResponse {
    //...
    @Serializable(with = IntToBoolSerializer::class)
    @SerialName("MyBoolField")
    val myBoolField: Boolean
}