In this example you will learn simple Apollo GraphQL client usage in android. We write ouyr example in Kotlin in android studio.

What is Apollo? Apollo tracks your GraphQL schemas in a registry to create a central source of truth for everything in your graph. You can read more about it here.

Example 1: Apollo GraphQL Client Example

This first example will teach you how to setup Apollo GraphQL and connect to the server.

Here is the demo of the created project:

Kotlin Android SharedPreferences

Kotlin Android SharedPreferences
Kotlin Android SharedPreferences

Apollo GraphQL Example Android

Step 1: Create Project

Open your android studio and create a new project.

Step 2: Add Dependencies

We need to add two dependencies to be able to use Apollo: the Apollo Runtime and Apollo Android support:

    implementation "com.apollographql.apollo:apollo-runtime:$apolloPluginVersion"
    implementation "com.apollographql.apollo:apollo-android-support:$apolloPluginVersion"

Step 3: Design Layouts

One layout will be included in the other.

repo_layout.xml

This will be included in the activity_main.xml. Add ImageView, EditTexts, TextViews and a Button:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/github_image_view"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="10dp"
        android:elevation="10dp"
        android:src="@drawable/github_icon"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/repo_name_edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="15dp"
        android:hint="@string/repository_name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/github_image_view" />

    <EditText
        android:id="@+id/owner_name_edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="15dp"
        android:hint="@string/owner_name_hint"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/repo_name_edittext" />

    <Button
        android:id="@+id/button_find"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="5dp"
        android:text="@string/button_text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/owner_name_edittext" />

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="5dp"
        android:layout_marginStart="5dp"
        android:layout_marginTop="5dp"
        android:elevation="@dimen/cardview_default_elevation"
        app:cardCornerRadius="@dimen/cardview_default_radius"
        app:cardElevation="@dimen/cardview_default_elevation"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_find">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <ProgressBar
                android:id="@+id/progress_bar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:layout_gravity="center_vertical|center_horizontal" />

            <TextView
                android:id="@+id/name_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:fontFamily="serif"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                tools:text="Name: ButterKnife" />

            <TextView
                android:id="@+id/description_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:fontFamily="serif"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                tools:text="Description: Library for View Binding" />

            <TextView
                android:id="@+id/forks_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:fontFamily="serif"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                tools:text="Forks:3011" />

            <TextView
                android:id="@+id/url_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:fontFamily="serif"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                tools:text="URL: http://github.com/" />

        </LinearLayout>

    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml

Add the following code in this layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:card_view="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/coordinator_layout"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:expandedTitleMarginEnd="50dp"
        android:alpha="0.9"
        app:expandedTitleMarginStart="20dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:statusBarScrim="@color/colorPrimary">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@android:color/white"
                android:textSize="30sp"
                android:text="GITHUB GRAPHQL"
                android:layout_marginBottom="20dp"
                android:fontFamily="sans-serif"
                android:textStyle="italic|bold"
                android:layout_gravity="center"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nested_scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginEnd="10dp"
        android:layout_marginStart="10dp"
        android:clipToPadding="false"
        app:behavior_overlapTop="90dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <include layout="@layout/repo_layout" />

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Step 4: Write GraphQL Query

Start by creating a folder inside the app/src/main called graphql and add the following graphql query:

/src/main/findRepo.graphql

query FindQuery($owner:String!,$name:String!){
  repository(owner:$owner, name:$name) {
    name
    description
    forkCount
    url
  }
}

/src/main/schema.json

Also download this schema.json file and add it to the same folder.

Step 5: Write Code

Create an Extension method to show Toast message:

Extension.kt

import android.content.Context
import android.widget.Toast

fun Context.showToast(msg: String) {
    Toast.makeText(applicationContext, msg, Toast.LENGTH_SHORT).show()
}

Then proceed to MainActivity.kt and create a function that sets up our Apollo GraphQL client using OkHttp. The function will return OkHttpClient

    private fun setupApollo(): ApolloClient {

Then instantiate OkHttp using the Builder pattern:

        val okHttp = OkHttpClient
                .Builder()

Add an intercepror where you chain our request:

                .addInterceptor { chain ->
                    val original = chain.request()
                    val builder = original.newBuilder().method(original.method(),
                            original.body())
                    builder.addHeader("Authorization"
                            , "Bearer " + BuildConfig.AUTH_TOKEN)
                    chain.proceed(builder.build())
                }

Build the OkHttpClient:

                .build()

Finally specify the server URL, then the OkhttpClient, then build then return the ApolloClient:

        return ApolloClient.builder()
                .serverUrl(BASE_URL)
                .okHttpClient(okHttp)
                .build()
    }

Here is the full code:

MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.apollographql.apollo.ApolloCall
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.api.Response
import com.apollographql.apollo.exception.ApolloException
import kotlinx.android.synthetic.main.repo_layout.*
import okhttp3.OkHttpClient
import java.util.logging.Logger

class MainActivity : AppCompatActivity() {

    private lateinit var client: ApolloClient

    companion object {
        val Log = Logger.getLogger(MainActivity::class.java.name)
        private const val BASE_URL = "https://api.github.com/graphql"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        client = setupApollo()
        button_find.setOnClickListener {
            progress_bar.visibility = View.VISIBLE
            client.query(FindQuery
                    .builder()
                    .name(repo_name_edittext.text.toString())
                    .owner(owner_name_edittext.text.toString())
                    .build())
                    .enqueue(object : ApolloCall.Callback<FindQuery.Data>() {

                        override fun onFailure(e: ApolloException) {
                            Log.info(e.message.toString())
                        }

                        override fun onResponse(response: Response<FindQuery.Data>) {
                            Log.info(" " + response.data()?.repository())
                            runOnUiThread {
                                progress_bar.visibility = View.GONE
                                name_text_view.text = String.format(getString(R.string.name_text),
                                        response.data()?.repository()?.name())
                                description_text_view.text = String.format(getString(R.string.description_text),
                                        response.data()?.repository()?.description())
                                forks_text_view.text = String.format(getString(R.string.fork_count_text),
                                        response.data()?.repository()?.forkCount().toString())
                                url_text_view.text = String.format(getString(R.string.url_count_text),
                                        response.data()?.repository()?.url().toString())
                            }
                        }

                    })
        }

    }

    private fun setupApollo(): ApolloClient {
        val okHttp = OkHttpClient
                .Builder()
                .addInterceptor { chain ->
                    val original = chain.request()
                    val builder = original.newBuilder().method(original.method(),
                            original.body())
                    builder.addHeader("Authorization"
                            , "Bearer " + BuildConfig.AUTH_TOKEN)
                    chain.proceed(builder.build())
                }
                .build()
        return ApolloClient.builder()
                .serverUrl(BASE_URL)
                .okHttpClient(okHttp)
                .build()
    }
}

Step 6: Add Permission

Add internet permission in your AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET" />

Run

Copy the code into your project or download the code in the reference links below.

Reference

Find the reference links below:

Number Link
1. Download code
2. Follow code author