Asynchronous Retrofit2 GCP API calls with Anko & Kotlin

Pyts Mike
4 min readApr 14, 2019

--

In Android development REST API calls are first class citizens what makes developers search for better ways, languages, frameworks, and libraries for the overall increase of productivity, scalability, and simplicity.

This article describes how to:
- Authenticate and authorize when using Google Cloud Platform APIs
- Set-up
Retrofit2 calls interface with parameters and dynamic headers
- Do API call on an example of
GCP BigQuery API
Libraries used: Retrofit 2, Google API client, Anko

Traditionally add next dependencies for Google API client, Retrofit 2 and Anko to your module build.gradle dependencies:

// Please update with actual libraries version
implementation "org.jetbrains.anko:anko:$version"
implementation "com.squareup.retrofit2:retrofit:$version"
implementation "com.squareup.retrofit2:converter-gson:$version"
implementation "com.google.api-client:google-api-client:$version"

GCP Authentification and authorization

IAM GCP Service

Each of the GCP REST APIs requires authentification and authorization. As for local development stage, it is recommended to use service accounts according to the Google Cloud Platform APIs description:

“Important: For almost all cases, whether you are developing locally or in a production application, you should use service accounts, rather than user accounts or API keys.”

Firstly access scopes for GCP API are defined, depending on the service it can require one or more but in the current example, we will get table data from GCP BigQuery what requires read-only scope.

authenticateAndAuthorize() function opens a stream for reading from service-account.json file located in application assets which is service account key and contains access rights info.

Note: service account should have access scopes described earlier in order to perform actions.

Anko’s doAsync { <actions>} is a simple way to perform background tasks in another thread. Antonio’s Leiva article about Anko usages for background tasks is a perfect source to start with.

As a result, an access token is received and will be used for a dynamic header in Retrofit call to BigQuery API.

Retrofit2 set-up

Retrofit2 is well-known and popular HTTP library and not all developers use it but for sure heard about it. There are other alternatives (like khttp for simple tests) but industry require to be on the peak of the wave and change your preferences in a timely manner.

“Retrofit is a type-safe HTTP client for Android and Java”

But not only those features make Retrofit so popular. In this example call to only one instance is shown. Instead in production you will meet API calls to different instances of the service and hold URL references as string variables or specify different headers, body or parameters all the time is not a wise choice.

GCPService interface is a skeleton for Retrofit features. Here @GET, @POST, @PUT, @DELETE, and @HEAD annotations are describing the type of a corresponding HTTP request. Also, the relative path of the URL is specified and later concatenated with baseUrl to form a request URL. This allows simple use of different APIs of the same service and up to you how to differentiate requests: create different functions and relative paths for them or specify @Path annotation as a function parameter and use it in a relative path.

getTable() parameters are handling annotations like @Header, @Query, @Body, @Path etc. and are used for dynamic values.

Note: All dynamic headers of the request should be passed as a function parameters.

retrofitBuilder defines:
- base URL
- converter factory (here BigQuery returns JsonObject in response and GsonConverterFactory is used but you can use your own converter).
- Retrofit requests are based on OkHttp and this allows to add logging interceptors which are skipped for simplicity.

Finally, a gcpService: class is created.

BigQuery API call

BigQuery GCP Service

BigQuery is Google Cloud Platform service and in the current example is used to keep data which is sent from the Android Things platform of original IoT project related to this example.

As a result of API call, table data is received and passed to real-time graph application.

“BigQuery is a serverless, highly-scalable, and cost-effective cloud data warehouse with an in-memory BI Engine and machine learning built in.”

Below pullData() function is presented which checks authorization and authentification token, calls authenticateAndAuthorize() function if needed and do asynchronous API call:

apiCall value contains the result of the execution of getTable() described in GCPService interface earlier. getTable() also receives two parameters:
- a dynamic string which is used as “Authorization” header (remember that dynamic headers can be used only as function parameters)
- query parameter which is added to the request URL and specified as @Query annotation earlier.

Final string

Retrofit can perform synchronous and asynchronous calls but for myself, I have found out that use of Anko’s doAsync simplify this and I can control whenever the task is performed in a separate thread or not. Also, Anko and Kotlin, as well as Android Studio, are written by JetBrains and I am a big fan of their ecosystem and approaches. You will see a lot of other uses of Anko especially for UI building later as this article is a small part of my in-house IoT project.

--

--