多个API调用来创建对象

时间:2016-07-03 23:14:22

标签: android rx-java retrofit2 rx-android

比如说,我有一个班级:

public class NI {

   private int id;
   @SerializedName("date")
   private String created_at;
   private String slug;
   private String type;
   private String link;

   private WPTitle title;

   private WPContent content;

   private WPExcerpt excerpt;
   @SerializedName("author")
   private int authorId;
   private int featured_media;
   private WPMedia media;
   List<Integer> categories;
}

另一堂课:

public class WPMedia {
  private int id;
  private String media_type;
  private String mime_type;
  private String source_url;
}

问题是WPMedia需要基于int featured_media的值进行单独的API调用。我如何构建一个可观察链,以便它获得NI类,然后另一个获得WPMedia然后将其设置在对象上?

我使用Retrofit进行API调用:

@GET("wp-json/wp/v2/posts")
Observable<ArrayList<NI>>getPostsObservableByCategory(@Query("categories") int category, @Query ("per_page") int limit, @Query("page") int skip);

@GET("wp-json/wp/v2/media/{id}")
Observable<WPMedia> getMediaObservable(@Path("id") int id);

2 个答案:

答案 0 :(得分:1)

我还不完全清楚你想要什么,但我会试一试。

我最初做的假设是NI上有一个带有签名public void setWPMedia(WPMedia media)的二传手。鉴于您提供的两个Retrofit函数定义,我会说您执行以下操作:

getPostsObservableByCategory(...)
  .flatMap(nis -> getMediaObservable(...)
    .first()
    .doOnNext(m -> nis.foreach(ni -> ni.setWPMedia(m)))
    .map(m -> nis));

逐行说明:

  • getPostsObservableByCategory(...)为您提供Observable,其中会发出NI个实例的列表。这些列表中每个media上的NI字段可能已设置,也可能未设置。
  • getMediaObservable(...)获取需要在相应列表中的每个元素上设置的WPMedia实例。
  • 我将getMediaObservable的排放数量限制为1,否则NI中的字段将被设置多次,我认为这不是理想的。如果getMediaObservable(...)函数/实现已经保证了这一点,则可以省略此行。
  • 设置字段被视为副作用,因此我们需要doOnNext,我们在其中循环NI个实例列表并将WPMedia字段设置为来自getMediaObservable
  • 我假设您之后想要列出NI个实例,因此我添加了一个map,只是将m替换为该列表。

希望这会帮助你!

答案 1 :(得分:0)

我为你找到了一个演示!我想你可以这样做:

@GET("/token")
public Observable<String> getToken();

@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);

...

getToken()
.flatMap(new Func1<String, Observable<User>>() {
    @Override
    public Observable<User> onNext(String token) {
        return getUser(token, userId);
    })
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
    @Override
    public void onNext(User user) {
        userView.setUser(user);
    }

    @Override
    public void onCompleted() {
    }

    @Override
    public void onError(Throwable error) {
        // Error handling
        ...
    }
});

Blog Link