GraphQL: настройка диспетчера подписок

Я новичок в GraphQL, поэтому хочу кое-что протестировать, прежде чем начинать свой собственный проект. В качестве тестовой базы данных я использую тестовые базы данных и службы Призма, а также Аполлон 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: Subscription manager is not configured

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

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

2
0
824
1

Ответы 1

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

Когда вы настраиваете 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 на это:

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

Привет. Извините за слишком поздний ответ. Спасибо за ответ, а как насчет метода normalizedCacheFactory() и cacheKeyResolver()? Как вы их реализовали?

Mirjalal 19.07.2019 13:17

@MirjalalTalishinski Отредактировано с учетом новой информации, я надеюсь, что это может вам помочь

Sefron Zilf 20.07.2019 19:58

К вашему сведению, просто добавления subscriptionTransportFactory достаточно, чтобы он "работал"

Sam 14.01.2020 16:53

Другие вопросы по теме