Learn Apollo GraphQL Client usage in Android using Kotlin and Android studio example.
Apollo tracks your GraphQL schemas in a registry to create a central source of truth for everything in your graph.
Example 1: Apollo GraphQL Client Example
This example project will teach you the following concepts:
- How to setup Apollo Graphql and connect to server.
Here is the demo:
Step 1: Create Project
The first step is to create a Android Project in Android Studio.
Step 2: Add Dependencies
Here are the dependencies we will need: apollo runtime and apollo 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 |