Skip to content

Networking 🌐

Architecture

Our Android Apps follow the MVP-Pattern. In the following code samples our focus will be on the model layer. To implement the model layer, we created the class Repository this class is responsible for making network requests and provides a simple API to the presenter layer.

In our Android Apps we use Dagger for Dependency Injection and OkHttp + Retrofit for network communication.

The most important class for the network communication is the class RepositoryModule. This class is responsible for providing instances for OkHttpClient, RetrofitApi and our Repository.

The following code snippets show the provides methods from the RepositoryModule.

OkHttpClient

The OkHttpClient builds the basic https connection to our servers. Authorization flow and certificate pinning are implemented on this level.

    @Provides
    fun providesOkHttpClient():  OkHttpClient {
        return OkHttpClient
                .Builder()
                //add interceptors, e.g. HttpLoggingInterceptor, ...
                //add certificate pinning
                //...
                .build()
    }

Retrofit

The GraphQlApi provides the REST-request to the GraphQl-API.

    @Provides
    fun providesRetrofitClient(okHttpClient: OkHttpClient): GraphQlApi {
        val gson = GsonBuilder()
                    .setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
                    .create()

        return Retrofit.Builder()
                .baseUrl("https://app.yoli.ai/next/")
                //we use rxJava to make asynchronous network calls
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                //automatically convert response/request to json string
                .addConverterFactory(ScalarsConverterFactory.create())
                //automatically convert strings from/to Date objects
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(okHttpClient)
                .build()
                .create(GraphQlApi::class.java)
    }

Sample flow

This chapter should showcase a sample flow of a GraphQl Request.

First the presenter calls a repository method and subscribes on the returned observable. After the data was successfully loaded, the observable emits a GraphQlPage which contains the requested data. How the GraphQlPage wraps the data is described in the chapter Using GraphQL in Android

    repository.getAccountsRx()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribeBy(
                    onNext = {
                        val accounts = it.data?.value?.accounts
                        if (accounts != null) {
                            view?.showAccounts(accounts)
                        }
                    },
                    onError = {
                        Timber.e(it)
                        view?.showNetworkError()
                    }
            )

The getAccountsRx() method calls request and provides the query and variables that should be send. Because Java looses type information for generics at runtime we need to define a TypeToken, which holds information about the returned generic type. The request method takes the given query and variables and executes the request. The returned JSON data is mapped to a GraphQlPage and gets returned to the presenter layer.

    fun getAccountsRx(): Observable<GraphQlPage<ValuePage<User>>> {
            return request(
                    GraphQlBody(
                            query = getQuery(Queries.ACCOUNT.filename),
                            variables = mapOf(
                                    Pair("language", LANGUAGE_DE)
                            )
                    ),
                    object : TypeToken<ValuePage<User>>() {}.type
            )
        }