GraphQL: настроить менеджер подписки - PullRequest
0 голосов
/ 26 декабря 2018

Я новичок в GraphQL, поэтому хочу кое-что проверить перед началом собственного проекта.В качестве тестовой базы данных я использую Prisma тестовые базы данных и службы и сервисы и Apollo Android в качестве библиотеки в моем приложении.Я почти закончил с query и mutation.Как следующий Я хочу что-то сделать с subscription.Итак, моя подписка на graphql выглядит следующим образом:

subscription observer {
  post {
    mutation
    node {
      id
      title
      text
      isPublished
    }
  }
}

Поскольку библиотека Apollo Android генерирует некоторые классы на основе моего кода graphql, я попытался использовать подписку observer следующим образом:

Interceptor interceptor = chain -> chain.proceed(chain.request());

OkHttpClient ohc = new OkHttpClient.Builder().addInterceptor(interceptor).build();

ApolloClient mApolloClient = ApolloClient.builder().serverUrl(ENDPOINT).okHttpClient(ohc).build();
mApolloClient.subscribe(ObserverSubscription.builder().build()).execute(new ApolloSubscriptionCall.Callback<ObserverSubscription.Data>() {
    @Override
    public void onResponse(@NotNull Response<ObserverSubscription.Data> response) {
        // do work here
    }

    @Override
    public void onFailure(@NotNull ApolloException e) {
        // catch exception
    }

    @Override
    public void onCompleted() {
        // some other stuff goes here
    }
});

При выполнении этого кода выдается следующее исключение:

java.lang.IllegalStateException: менеджер подписки не настроен

Это сообщение приходит от здесь иэто напрямую связано с this .

Мой вопрос, есть ли способ использовать подписки с помощью apollo-android в приложении Android?

1 Ответ

0 голосов
/ 22 февраля 2019

Во-первых, извините за поздний ответ, я просто застрял с той же проблемой, и, используя информацию со многих сайтов, я сделал успешную подписку.

Когда вы настраиваете свой ApolloClient, вам нужночтобы определить некоторые дополнительные параметры:

Первый - это нормализованный кеш, для этого я использую конфигурацию по умолчанию:

 NormalizedCacheFactory normalizedCacheFactory(){
        return new LruNormalizedCacheFactory(EvictionPolicy.builder().maxSizeBytes(10 * 1024).build());
    }

И cacheKeyResolver:

CacheKeyResolver cacheKeyResolver(){
        return new CacheKeyResolver() {
            @Nonnull
            @Override
            public CacheKey fromFieldRecordSet(@Nonnull ResponseField field, @Nonnull Map<String, Object> recordSet) {
                if (recordSet.containsKey("id")) {
                    String id = (String) recordSet.get("id");
                    return CacheKey.from(id);
                }
                return CacheKey.NO_KEY;
            }

            @Nonnull @Override
            public CacheKey fromFieldArguments(@Nonnull ResponseField field, @Nonnull Operation.Variables variables) {
                return CacheKey.NO_KEY;
            }
        };
    }

В cacheKeyResolver вам нужно указать, как будут идентифицироваться идентификаторы ваших объектов, в моем случае все они содержат «id» в начале своего имени.Вы можете добавить больше параметров, используя ту же структуру.

Оба эти конфига находятся внутри компоновщика ApolloClient:

Map<String, Object> connectionParams = new HashMap<>();
        return ApolloClient.builder()
                .serverUrl(urlBaseDeDatos)
                .normalizedCache(normalizedCacheFactory(),cacheKeyResolver())
                .okHttpClient(okHttpClient())
                .subscriptionConnectionParams(connectionParams)
                .subscriptionTransportFactory(new WebSocketSubscriptionTransport.Factory(urlBaseDeDatos, okHttpClient()))
                .build();

Последние 2 являются важными, так как они контролируют вашу подписку (илиЯ думаю, что они делают), как только я определил эти 2, я мог бы сделать подписку.Мои connectionParams пусты, так как я не использую токен аутентификации или что-то в этом роде.

Теперь для подписки:

private Flowable<Response<TaskStatusChangedSubscription.Data>> subscription(){
        apolloClient.clearNormalizedCache();
        return Rx2Apollo.from(apolloClient.subscribe(TaskStatusChangedSubscription
                .builder()
                .build()));
    }

Обычный поток с методом Apollo.subscribe инекоторая помощь от RxJava и выполнение .subscribe () для той же функции или для другой (например, одноразовой).

Наконец (извините за все объяснения из ранее, но это может помочь кому-то еще), вашпроблема должна быть решена, если вы измените свой Apollo Builder на это:

Map<String, Object> connectionParams = new HashMap<>();
ApolloClient mApolloClient = ApolloClient.builder().serverUrl(ENDPOINT).okHttpClient(ohc).subscriptionConnectionParams(connectionParams)
                .subscriptionTransportFactory(new WebSocketSubscriptionTransport.Factory(ENDPOINT, okHttpClient()))
                .build();
...