Search code examples
androidkotlinapollo-android

How to create a JSON CustomTypeAdapter in Apollo GraphQL on Android with Kotlin


I'm struggling to figure out how to add a CustomTypeAdapter to my ApolloClient.

For a mutation, our server is expecting json input. The corresponding iOS app is passing in a json string.

When I pass in a string I get a message asking if I've forgotten to add a customtype.

Here is my attempt:

build.gradle

apollo {
        useSemanticNaming = true
        customTypeMapping['ISOTime'] = "java.util.Date"
        customTypeMapping['JSON'] = "java.lang.JSONObject"
    }

Here's where it is instantiated.

val jsonCustomTypeAdapter = object : CustomTypeAdapter<JSONObject> {
                override fun decode(value: CustomTypeValue<*>): JSONObject {
                    return JSONObject()
                }

                override fun encode(value: JSONObject): CustomTypeValue<*> {
                    return CustomTypeValue.GraphQLJsonString(value.toString())
                }
            }

 mApolloClient = ApolloClient
                .builder()
                .serverUrl(baseUrl)
                .addCustomTypeAdapter(jsonCustomTypeAdapter)
                .normalizedCache(cacheFactory, CacheKeyResolver.DEFAULT)
                .httpCache(ApolloHttpCache(cacheStore, null))
                .okHttpClient(mHttpClient)
                .build()

It seems Apollo has generated a CustomType enum implementing ScalarType but I'm not sure if or how to use it.

@Generated("Apollo GraphQL")
public enum CustomType implements ScalarType {
  JSON {
    @Override
    public String typeName() {
      return "Json";
    }

    @Override
    public Class javaType() {
      return Object.class;
    }
  },

  ID {
    @Override
    public String typeName() {
      return "ID";
    }

    @Override
    public Class javaType() {
      return String.class;
    }
  }
}

I've attempted the example given on the apolloandroid github but it hasn't worked for me and it is in Java and after I convert it to Kotlin, it doesn't compile.

Any hints or direction to persue would be appreciated. Thanks.


Solution

  • It turns out Apollo had auto generated the type and all I had to do was declare it correctly in the build.gradle. I didn't need to add any custom type adapter to the ApolloClient.

    NOTE: The type Json was provided by our server.

    apollo {
            useSemanticNaming = true
            customTypeMapping['ISOTime'] = "java.util.Date"
            customTypeMapping['Json'] = "java.lang.String"
        }