Apollo and RxJava: Android GraphQL the Right Way
Tags: graphql, android, rxjava, apollo
Published: 2021-07-25 16:01:57

## Introduction

Since its inception, GraphQL has grown to become a very popular framework for building backend APIs. However, I still don’t see it used that often on Android. I think the reason is that there aren’t many resources on using GraphQL on Android, and what does exist is outdated or doesn’t take advantage of new technologies. In this article, I want to present a “best practices” approach to setting up a GraphQL client on Android. We’ll make a simple Android app that uses the SpaceX GraphQL API to display a list of rockets. By taking advantage of [Apollo Android](https://github.com/apollographql/apollo-android) and [RxJava](https://github.com/ReactiveX/RxJava), we’ll do GraphQL on Android the right way.

## Setup
Before we get started, we have to get all our dependencies ready. First, paste the following into your project level `build.gradle`:

```groovy
buildscript {
    repositories {
      ...
    }
    dependencies {
        classpath "com.apollographql.apollo:apollo-gradle-plugin:2.4.1"
        ...
   }
}

allprojects {
    repositories {
        ...
        // RxJava repo
        maven { url "https://oss.jfrog.org/libs-snapshot" }
    }
}
```

This will add the apollo plugin and a maven repo we need tor RxJava. Next, add these dependencies and plugin to your app level `build.gradle`:

```groovy
dependencies {
    ...
    // Apollo
    implementation "com.apollographql.apollo:apollo-runtime:2.4.1"
    implementation "com.apollographql.apollo:apollo-rx3-support:2.4.1"

    // RxJava
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
}

apply plugin: "com.apollographql.apollo"
```

Here we add two Apollo related dependencies, one for the library itself and another for Rx support. We also add RxAndroid, an Android port of RxJava, and RxJava itself. We add RxJava explicitly because RxAndroid isn’t updated as often, so defining it manually lets us stay up to date with bug fixes. Don’t forget to add `apply plugin: “com.apollographql.apollo”` at the end of your gradle file, otherwise you’ll run into compiler issues later.

## Writing GraphQL Queries

Create the directory `src/main/graphql/com/example`, but replace example with your own package name. After that, run the following command to fetch a GraphQL schema:

```
./gradlew downloadApolloSchema 
--endpoint="https://api.spacex.land/graphql/" 
--schema="src/main/graphql/com/example/schema.json"
```

> Replace `./gradlew` with `gradlew.bat` if you're on Windows.

This command will run an introspection on the SpaceX API and create a `schema.json` for us. Next we'll write our GraphQL query, which we’ll use to fetch a list of rockets. Create a file called `rockets.graphql` in the same directory as `schema.json` and paste the following:

```graphql
query RocketsQuery {
    rockets {
        id
        name
        description
    }
}
```

This is a very basic GraphQL query that targets the rockets endpoint and fetches a list of rockets, with each entry containing the rocket's id, name, and description. The API actually provides a lot more information than this, but we only need these three data points. Since GraphQL lets us fetch only what we need, we don't have to slow down our requests with unnecessary information.‌ If you want to learn more about GraphQL in particular, [this article](https://medium.com/free-code-camp/so-whats-this-graphql-thing-i-keep-hearing-about-baf4d36c20cf) is great place to start.

Now that we wrote our query, build the project. Apollo will read the graphql files we created and automatically generate classes that we’ll use to make queries against the server. If you set your project view to Android, you should see the following:

![1_uHDE8Zo5AsLlPnJoAWqGIQ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p7yi3plaw39gq5g16hb.png) 

## Making a GraphQL Request

Now that we have all our GraphQL stuff setup, we can start writing some Java code. It’s good practice to keep all our server related code in one class, which we’ll call `Server`. Here's the shell of that class:

```java
class Server {
    private static ApolloClient apolloClient;
    
    private static ApolloClient getApolloClient() {
        if (apolloClient == null) {
            //Build the Apollo Client
            String serverUrl = "https://api.spacex.land/graphql/";
            OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
            apolloClient = ApolloClient.builder()
                    .serverUrl(serverUrl)
                    .okHttpClient(okHttpClient)
                    .build();
        }
        return apolloClient;
    }
}
```

This class uses the singleton pattern to create an `ApolloClient` instance. We'll use this helper method in our queries so we don't have to create a client with every query.

Next let’s make a method for our `rockets` query:

```java
public static Observable<Response<RocketsQuery.Data>> fetchRockets() {
    ApolloQueryCall<RocketsQuery.Data> call = getApolloClient()
            .query(new RocketsQuery());

    return Rx3Apollo.from(call)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .filter((dataResponse -> dataResponse.getData() != null));
}
```

This code is pretty dense, so let’s go through it slowly. First we create an `ApolloQueryCall` object with `RocketsQuery`, the class that was generated from the GraphQL file we wrote earlier. This object defines the GraphQL query we want to make against the SpaceX API.‌

We then use the helper class `Rx3Apollo` to convert the call into an RxJava object, which lets us do all our Rx magic on it. `subscribeOn` specifies that we want this request to be run on a background thread. With `observeOn`, we say that we want to handle the response on the main thread because we'll update the UI using the response. Finally, we add a filter to toss out null responses to prevent any null pointer exceptions.

This method returns an `Observable` that we can then use in our Activity code to handle loading and error states and update the UI when we get a response.

Now we’ll use the `fetchRockets` method we created to populate a list:

```java
 // Show loading
ProgressBar progressBar = findViewById(R.id.main_progressBar);
progressBar.setVisibility(View.VISIBLE);

Server.fetchRockets().subscribeWith(new DisposableObserver<Response<RocketsQuery.Data>>() {
    @Override
    public void onNext(@NonNull Response<RocketsQuery.Data> dataResponse) {
        if (dataResponse.getData() != null) {
            RocketsAdapter adapter = new RocketsAdapter(dataResponse.getData().rockets(),MainActivity.this);
            recyclerView.setAdapter(adapter);
        }
    }

    @Override
    public void onError(@NonNull Throwable e) {

    }

    @Override
    public void onComplete() {
         // Query's done, so hide loading
         progressBar.setVisibility(View.GONE);
    }
});
```

In this code snippet, we first show the loading indicator, because we’re about to fetch our data. We then use our `Server` class to do a rockets query and create a `DisposableObserver` to handle the result. This is one of the benefits of using RxJava with Apollo Android. `DisposableObserver` has three methods we can use to handle the result: `onNext`, `onError`, and `onComplete`. `onNext` is called when a valid response is received, and `onError` is called if an error occurs. Regardless of the outcome, `onComplete` is called once the request is completed. This lets us define our loading, error, and data states separately, which greatly simplifies our code. In this snippet, we attach the rockets to a custom adapter([code here](https://github.com/Ninjaman494/Android-GraphQL-Example/blob/main/app/src/main/java/com/n494/spacex/RocketsAdapter.java)) and then hide the loading indicator. Notice that the loading part is handled in `onComplete`, because we want to hide it even if an error occurs.

## Conclusion
In this article we went through the right way to use GraphQL on Android by taking advantage of the Apollo Android and RxJava libraries. However, the example we went through is one the simplest request scenarios. For more advanced scenarios like parallel and dependent requests, check out this article’s [companion repo](https://github.com/Ninjaman494/Android-GraphQL-Example). You can also [read my next article](https://levelup.gitconnected.com/easily-handle-advanced-requests-on-android-with-graphql-and-rxjava-dca2cc0cecee), where we’ll take a closer look at some of the advanced examples in this repo.

As always, thanks for reading and let me know in the comments if this helped you out!