Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use GraphQL with Retrofit on Android?

I'm new to GraphQL but I have been using Retrofit for a while now and its easy to use and fast. GraphQL is much different than rest apis in terms of how you pass data. There really are not too many tutorials out there on using GraphQL with Android, I was only able to find this video (https://www.youtube.com/watch?v=P0uJHI7GjIc&t=1s) but there is no real code in there.

In my current code for retrofit calls I have an endpoint I set like so:

final RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(endPoint)
                .build();
        T service = restAdapter.create(clazz);

Then I call a rest service like this:

@GET("/users/{login}")
    Observable<Github> getUser(@Path("login") String login);

Now with GraphQL you only have a base url and no service path. Also if you are querying like userId=1 then you have to send as Post with Body parameters:

operationName: arbitrary name ,
query: "{users(userid:$userId){username}}, 
variables: "{"userId":1}"

I'm just not sure how this translates to Retrofit

like image 569
Mike6679 Avatar asked Nov 29 '16 21:11

Mike6679


People also ask

How does GraphQL work with Android?

Consume your GraphQL API on Android Devices with Apollo Android. Apollo Android is a GraphQL client that generates type-safe Kotlin models from your GraphQL queries. It also handles parsing and caching so you can focus on what matters most to your users and build beautiful mobile apps.

Can you use GraphQL without Apollo?

Unfortunately, while I'm sure their platform is great, if you're setting up a fresh GraphQL API you should not start with Apollo. It certainly might be useful later, but on day 1 it's a trap, and you'll make your life simpler and easier if you avoid it entirely.

What is retrofit used for in Android?

Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services.

Can you use GraphQL with Swift?

Add run script to your build phases above the compile sources section. This script downloads the schema and generates Swift types for your queries. You can easily change the GraphQL endpoint in this script to connect to your GraphQL backend.


2 Answers

In your manifest to add

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

Your dependencies

// Kotlin Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4'

//OkHttp
implementation ("com.squareup.okhttp3:okhttp:3.12.12"){
  force = true //API 19 support
}
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.12'

//retrofit
implementation "com.squareup.retrofit2:retrofit:2.7.1"
implementation "com.squareup.retrofit2:converter-scalars:$2.7.1"

Also Java 8 compatibility

android {

    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

With the service

import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST

interface GraphQLService {

    @Headers("Content-Type: application/json")
    @POST("/")
    suspend fun postDynamicQuery(@Body body: String): Response<String>
}

you can create a object

import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory

object GraphQLInstance {

    private const val BASE_URL: String = "http://192.155.1.55:2000/"

    val graphQLService: GraphQLService by lazy {
        Retrofit
            .Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(ScalarsConverterFactory.create())
            .build().create(GraphQLService::class.java)
    }
}

In the activity you can create this method

private fun post(userId: String){
    val retrofit = GraphQLInstance.graphQLService
    val paramObject = JSONObject()
    paramObject.put("query", "query {users(userid:$userId){username}}")
    GlobalScope.launch {
        try {
            val response = retrofit.postDynamicQuery(paramObject.toString())
            Log.e("response", response.body().toString())
        }catch (e: java.lang.Exception){
            e.printStackTrace()
        }
    }
}

You can check the example in GitHub and my post

Note: if you need a mutation should be to change this line

paramObject.put("query", "query {users(userid:$userId){username}}")

to

paramObject.put("query", "mutation {users(userid:$userId){username}}")
like image 93
Cabezas Avatar answered Oct 25 '22 18:10

Cabezas


Building Queries & Parsing responses for GraphQL is not straightforward. If you are using this on pet-projects, i recommend to start exploring Apollo. This client is under serious development but you can already have a look and play with it.

https://github.com/apollographql/apollo-android

I enjoyed working with Apollo so far, and there are nice features on their roadmap: RxJava Integration, Retrofit, Subscriptions and support for AutoValue

like image 20
Entreco Avatar answered Oct 25 '22 19:10

Entreco