Authorization using interceptors for mutation Operation in Java using Apollo Android Client

Team,
I was exploring the Apollo Android client in my Java Application. So far it looks good and i was able to execute the Query Functionality.

While this looks great and i am able to get the results, I am trying to explore the Mutation Scenario, where-in we using the following Mutation operation

mutation BookTrip($id:[ID]!) {
    bookTrips(launchIds:$id) {
        success
        message
    }
}

I tried executing the mutation using following code

List<String> tripList= new ArrayList<String>();
        tripList.add("Test Mutation 992");
        tripList.add("Test Mutation 993");
        apolloClient.mutate(new BookTripMutation(tripList)).enqueue(new ApolloCall.Callback<BookTripMutation.Data>() {
            @Override
            public void onResponse(@NotNull Response<BookTripMutation.Data> response) {
                System.out.println("Apollo Launch site: " + response.getData().bookTrips());
            }

            @Override
            public void onFailure(@NotNull ApolloException e) {
                System.out.println("Apollo Error:" + e);
            }
        });

However, i am getting the following exception

Exception in thread "OkHttp Dispatcher" java.lang.NullPointerException
	at org.example.Main$2.onResponse(Main.java:56)
	at com.apollographql.apollo.internal.RealApolloCall$1.onResponse(RealApolloCall.java:253)
	at com.apollographql.apollo.internal.interceptor.ApolloCacheInterceptor$1$1.onResponse(ApolloCacheInterceptor.java:75)
	at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor$1.onResponse(ApolloParseInterceptor.java:54)
	at com.apollographql.apollo.internal.interceptor.ApolloServerInterceptor$executeHttpCall$1.onResponse(ApolloServerInterceptor.kt:114)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

It looks like some authentication problem, i was going through the following link

But most of the initialization code for interceptors is Kotlin based.

Can some-one please let me know what how will i initialize interceptors using a custom okhttp client in java?

Any pointers to the document or sample example code snippet will help here.

Thanks in Advance.

Hi! The code to set an OkHttp interceptor in Java is fairly similar :blush: It would look like this:

class AuthorizationInterceptor implements Interceptor { 
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request request = chain.request().newBuilder()
                .addHeader("Authorization", (Your token))
                .build();

        return chain.proceed(request);
    }
}

// ...

ApolloClient apolloClient = ApolloClient.builder()
        .serverUrl(...)
        .okHttpClient(new OkHttpClient.Builder().addInterceptor(new AuthorizationInterceptor()).build())
        .build();


@Benoit_Lubek : I tried the code but still getting the same error, I generated the Authorization token from sandbox Studio and then executed the following code

ApolloClient apolloClient = ApolloClient.builder()
                .serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
                .okHttpClient(new OkHttpClient.Builder().addInterceptor(new AuthorizationInterceptor()).build())
                .build();

        List<String> tripList= new ArrayList<String>();
        tripList.add("Test Mutation 992");
        tripList.add("Test Mutation 993");
        apolloClient.mutate(new BookTripMutation(tripList)).enqueue(new ApolloCall.Callback<BookTripMutation.Data>() {
            @Override
            public void onResponse(@NotNull Response<BookTripMutation.Data> response) {
                System.out.println("Apollo Launch site: " + response.getData().bookTrips());
            }

            @Override
            public void onFailure(@NotNull ApolloException e) {
                System.out.println("Apollo Error->" + e);
            }
        });

I used the Interceptor code suggested by you placing a token retrieved from the sandbox explorer, still getting the following error

Exception in thread “OkHttp Dispatcher” java.lang.NullPointerException
at org.example.Main$2.onResponse(Main.java:62)
at com.apollographql.apollo.internal.RealApolloCall$1.onResponse(RealApolloCall.java:253)
at com.apollographql.apollo.internal.interceptor.ApolloCacheInterceptor$1$1.onResponse(ApolloCacheInterceptor.java:75)
at com.apollographql.apollo.internal.interceptor.ApolloParseInterceptor$1.onResponse(ApolloParseInterceptor.java:54)
at com.apollographql.apollo.internal.interceptor.ApolloServerInterceptor$executeHttpCall$1.onResponse(ApolloServerInterceptor.kt:114)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)

Can you please suggest if i am missing any steps here?

Thank You!

This NullPointerException is due to getData() being null when there is GraphQL level error. When it is null you can instead look at .getErrors() and check if this one has useful information, like so:

            public void onResponse(@NotNull Response<BookTripMutation.Data> response) {
                if (response.getErrors() != null && response.getErrors().size() > 0) {
                    System.out.println("There were some errors: " + response.getErrors());
                } else {
                    System.out.println("Apollo Launch site: " + response.getData().bookTrips());
                }
            }

In your case the error is certainly due to "Test Mutation 992" not being valid trip ids. Try with "109" instead for instance.

Thank You @Benoit_Lubek , that worked well. Appreciate your help!!.

Team with respect to Subscription Feature, is there any API Change in the Android V2 API for setting the subscriptionTransportFactory.

As per the code-snippet in the documentation, i am trying to get the Subscription Functionality to work using the following code-snippet

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new AuthorizationInterceptor())
                .build();

ApolloClient apolloClient = ApolloClient.builder()
                .serverUrl("https://apollo-fullstack-tutorial.herokuapp.com/graphql")
                .subscriptionTransportFactory(WebSocketSubscriptionTransport.Factory("wss://apollo-fullstack-tutorial.herokuapp.com/graphql",okHttpClient))
                .okHttpClient(okHttpClient)
                .build();

apolloClient.subscribe(new TripsBookedSubscription())
.execute(new ApolloSubscriptionCall.Callback<TripsBookedSubscription.Data>(){

            @Override
            public void onCompleted() {
                System.out.println("Subscription Completed");
            }
            @Override
            public void onTerminated() {
                System.out.println("Subscription Terminated");
            }
            @Override
            public void onConnected() {
                System.out.println("Subscription Connected");
            }
            @Override
            public void onResponse(@NotNull Response<TripsBookedSubscription.Data> response) {
                if (response.getErrors() != null && response.getErrors().size() > 0) {
                    System.out.println("There were some errors: " + response.getErrors());
                } else {
                    System.out.println("Apollo Increment Subscription: " + response.getData());
                }
            }

            @Override
            public void onFailure(@NotNull ApolloException exception) {
                System.out.println("Apollo Subscription Error->" + exception);
            }
        });

however its failing in the build step by throwing the following error:

error: cannot find symbol
                .subscriptionTransportFactory(WebSocketSubscriptionTransport.Factory("wss://apollo-fullstack-tutorial.herokuapp.com/graphql",okHttpClient))
                                                                            ^
  symbol:   method Factory(java.lang.String,okhttp3.OkHttpClient)
  location: class com.apollographql.apollo.subscription.WebSocketSubscriptionTransport

I can see the contract has changed from version 2 to version 3 of the API
I am using version 2.5 dependency in Gradle

plugins {
    id("java")
    id("com.apollographql.apollo").version("2.5.11")
}

Can some-one please share insights on what is wrong here? or if i am invoking the API with wrong Parameters?

Thank You!!

I think you’re just missing a new?

It should be:

.subscriptionTransportFactory(new WebSocketSubscriptionTransport.Factory

@Benoit_Lubek : It didn’t help either, getting this issue while building after the changes suggested

‘subscriptionTransportFactory(com.apollographql.apollo.subscription.SubscriptionTransport.Factory)’ in ‘com.apollographql.apollo.ApolloClient.Builder’ cannot be applied to ‘(com.apollographql.apollo.subscription.WebSocketSubscriptionTransport.Factory)’

I am referring the docs from 11. Write your first subscription - Apollo GraphQL Docs

Hi! I think this is an instance of a bug in the IDE that incorrectly highlight this as an error. WebSocketSubscriptionTransport.Factory does implement SubscriptionTransport.Factory so this is valid. You should be able to compile / run despite the highlighted error.

1 Like

Thank You @Benoit_Lubek , true, i was able to build and run the Subscription functionality by building using command line, Appreciate all your help.