Using the apollo graphql client for Android

GraphQL is a new way of describing and executing your API requests. It allows you to write more discoverable, more flexible and more maintainable APIs amongst other advantages (read this and this for more advantages).

This post will focus on how to use the apollo-android client to integrate graphql seamlessly into your Android Studio workflow as well as describe quickly the internals of the plugin.

Apollo-Android is still in its early days but it's already possible to do lots and lots of very interesting things. For the source code and details, feel free to hit the official repo there: https://github.com/apollographql/apollo-android.

Setup your build.gradle

Add the following lines to your build.gradle:

buildscript {
    repositories {
        // these are the repositories where to look for the plugin and its dependencies 
        maven { url "https://jitpack.io" }
        mavenCentral()
    }
    dependencies {
        // this is the plugin
        classpath 'com.apollographql.android:gradle-plugin:0.1.0'
    }
}

repositories {
    // these are the repositories where to look for libs and runtime
    mavenCentral()
}

dependencies {
    compile 'com.apollographql.android:api:0.1.0' // the apollo runtime classes needed by auto-generated code
    compile 'com.squareup.retrofit2:retrofit:2.1.0' // retrofit2
    compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' // rxjava2 to use the Observables stuff
    compile 'com.apollographql.android:converter-pojo:0.1.0' // converts retrofit responses to pojos (ApolloConverterFactory)
}

apply plugin: 'com.apollographql.android'

apollo {
    // this tells the apollo compiler to generate actual static classes instead of just interfaces (more on that later)
    generateClasses = true
}

At this points, you'll have noticed that apollo is twofolds:

  • gradle-plugin: takes your .graphql files and auto-generates code.
  • api: is a library used by auto-generated code to execute the queries.

Download your schema

You'll need a decently recent version of node to run apollo-codegen. Then from your android project directory, do the following:

> npm install -g apollo-codegen 
> mkdir -p app/src/main/graphql
> apollo-codegen download-schema http://your.domain/graphql --output app/src/main/graphql

The schema files describes all the types and hierarchy used by your endpoint.

Describe your query

Now create a file under app/src/main/graphql and type your sql query:

query DroidDetails {
  species(id: "c3BlY2llczoy") {
    id
    name
    classification
  }
}

That's all the plugin needs to generate the model classes automatically !

Receiving data with retrofit

Write your retrofit interface as usual:

interface ApiService {
  @GET("/graphql") Observable<Response<DroidDetails.Data>> droidDetails(@Query("query") String query);
}

Create your Retrofit instance:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://your.domain/")
        .client(okHttpClient)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()).create())
        .addConverterFactory(new ApolloConverterFactory.Builder().build())
        .build();

The magic here is ApolloConverterFactory. That will automatically convert the gson response to instances of DroidDetails.Data

ApiService service = retrofit.create(ApiService.class);
service.droidDetails(DroidDetails.QUERY_DOCUMENT)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(data -> {
            // do something with data
        }, error -> {
            // do something with error
        });

More stuff

using POST instead of GET

You can use POST instead of GET if you want to. That might actually be easier if you're planning to send variables as part of your queries. apollo-api has the OperationRequest type that you can use with MoshiConverterFactory to send the POST body. If you want to use that, you'll most likely the moshi converters:

compile 'com.apollographql.android:converter-pojo:0.1.0'

apollo-codegen & apollo-compiler

Apollo-codegen is a node project that parses graphql and generates an intermediate representation (IR). You can find the files in the generated folder of your project if you're curious.

Apollo-compiler takes these IR files and turns them into the actual classes implementations using javapoet

About generateClasses

Remember this bloc:

apollo {
    // this tells the apollo compiler to generate actual static classes instead of just interfaces (more on that later)
    generateClasses = true
}

If you omit it, the compiler will generate interfaces instead of classes. So if you have your own framework to generate immutable classes like AutoValue for an example you can reuse that.

Conclusion

It is still the very early days of apollo-android but the tools are already quite useful. They allow you to autogenerate model classes and fill them from network responses without using reflection.
That will make your projects both more maintainable and faster compared to using for an example, gson converters. There's really no reason not to start using it now.