Клиент Jersey RxJava и набор конечных точек ресурсов

Я очень-очень новичок в RxJava, и я все еще пытаюсь понять поток данных, но я хочу знать, возможно ли это, прежде чем отправиться в кроличью нору.

Цель: отделить ресурсы API и разрешить их распределение, а также предоставить клиентам (веб-сайтам и мобильным устройствам) гибкость для получения данных на основе ссылок href, предоставленных лишь нескольким «известным» Конечные точки API.

У меня есть коллекция объектов JSON из одного API, где каждый json имеет поле «href», которое предоставляет ссылку на ресурс API, где можно получить полную информацию о данных. Например:

{
   {
      name: "assassins_creed",
      href: "games/assassins_creedId123"
   },
   {
      name: "bioshock",
      href: "games/bioshockId456"
   },
   {
      name: "clean_code",
      href: "books/clean_codeId789"
   },
   {
      name: "christmas",
      href: "events/xmas001"
   }
}

После получения этой коллекции я хотел бы сделать вызов соответствующего ресурса, используя это значение href, и сохранить результат в коллекции, такой как массив JSON.

Я сопоставляю строки из списка объектов JSON в другой список, а затем пытаюсь добавить их в Observable, чтобы я мог асинхронно извлекать каждый ресурс в один и тот же ответ.

Я использовал пример Джерси в качестве ссылки, и я обеспокоен тем, что он не может принимать динамические ссылки href и возвращать ответ, который я хотел бы.

Пока остановился на:

@Override
public List<JSONObject> getUsersDashboard(TokenModel token, String userId, @Suspended final AsyncResponse async) {
    List<JSONObject> list = //Database request to get items for userId
    List<String> hrefLinks = list.stream()
            .map(e -> (String) e.get("href"))
            .collect(Collectors.toList());

    final Queue<String> errors = new ConcurrentLinkedQueue<>();

    Observable.just(new JSONArray())
            .zipWith(dashboard(token.getAccessToken(),"plhUrl", errors), (array, objects) -> {
                array.add(objects);
                return array;
            })
            .subscribe(response -> {
                //errors?
                async.resume(response);
            }, async::resume);
}

private Observable<List<JSONObject>> dashboard(String access, String urlFragment, Queue<String> errors) {
     Client client = ClientBuilder.newClient();
     return RxObservable.from(client).target(urlFragment).request()
            .header("Authorization", access)
            .rx()
            .get(new GenericType<List<JSONObject>>(){})
            .onErrorReturn(throwable -> {
                errors.offer(throwable.getMessage());
                return Collections.emptyList();
            });
}

Я не решался поместить это в цикл for, чтобы создать Observables для каждой записи hrefLinks.

Как я могу получить ответы от нескольких ресурсов в один согласованный ответ для клиента?


person fakataha    schedule 12.01.2017    source источник


Ответы (1)


Оператор flatMap — это то, что вам нужно. Вы можете создавать ссылки href в потоке, чтобы в операторе flatMap вы преобразовывали каждую ссылку в новую наблюдаемую, которая распространяла бы свой результат в исходный поток. Я думаю, что это именно то поведение, которое вы описали.

РЕДАКТИРОВАТЬ: библиотека Retrofit предоставляет приятный интерфейс для создания наблюдаемых из ссылок. Чтобы подробнее рассказать о вашем примере, вам сначала нужно преобразовать объект коллекции в какой-то Iterable с помощью оператора map. Когда у вас есть интерактивный объект, используйте flatMap для создания наблюдаемого элемента, принадлежащего Iterable, используя Observable.from(). Это будет испускать ссылки как отдельные излучения. Затем вы снова используете flatMap, чтобы преобразовать каждую ссылку в наблюдаемый сетевой запрос, который перенаправляет выброс обратно в исходный поток.

getCollectionObjectObservable()
  .map(result -> iterable) // transform the object into Iterable( ie. List ) 
  .flatMap(iterable -> Observable.from(iterable))
  .flatMap(link -> createRequestObservable(link))
  .subscribe(result -> /* process the result of each item here */ )
person koperko    schedule 12.01.2017
comment
getCollectionObjectObservable(): это метод в библиотеке Retrofit? - person fakataha; 12.01.2017
comment
После некоторой работы и помощи у меня все заработало, спасибо! - person fakataha; 14.01.2017