首页 > 解决方案 > 使用 Retrofit + Rx 链接 API 请求

问题描述

我正在尝试使用这个API 为 Hacker News 开发一个客户端,只是为了学习 Android 是如何工作的,作为一个个人项目。我尝试遵循一些教程,但我被困在某个点上。

我想检索前 N 个故事的标题、赞成票等。这可以通过以下方式使用此 api 完成:

  1. 向 api 发出请求以检索热门帖子的 ID(准确地说是 500 个)
  2. 对于每个 ID,向 api 的帖子端点发出请求以检索详细信息。

似乎我被困在如何为我想要的帖子创建 N 个不同的网络请求,检索它们并将它们放在列表中,然后将它们显示在我的片段上。 我正在尝试使用存储库来遵循 MVVM 模式。相关文件在这里:

新闻API.kt:

interface NewsApi {

    @GET("topstories.json")
    fun getTopStories() : Single<List<Int>>

    @GET("item/{id}")
    fun getItem(@Path("id") id: String): Single<News>
}

MainRepository.kt (I):

interface MainRepository {

    fun getTopStoryIDs(): Single<List<Int>>

    fun getStory(storyId: Int): Single<News>

    fun getTop20Stories(): Single<List<News>>
}

News对象是一个简单的数据类,其中包含从 中返回的所有 JSON 字段item/{id},因此我将其省略。

这是我的存储库,实现:

class DefaultMainRepository @Inject constructor(
    private val api: NewsApi
) : MainRepository {
    override fun getTopStoryIDs(): Single<List<Int>> {
        return api.getTopStories()
    }

    override fun getStory(storyId: Int): Single<News> {
        return api.getItem(storyId.toString())
    }

    override fun getTop20Stories(): Single<List<News>> {
        TODO("HOW?")
    }
}

我最关心的问题是:

  1. 如何使用 Retrofit / RxJava 以这种方式进行链式 API 调用?我已经使用 flatMap 查看了以前的答案,但就我而言,使用 Int 列表,我实际上并不知道如何正确地做到这一点。
  2. 这是解决这个问题的正确方法吗?我是否应该放弃我所做的架构选择,并尝试以全新的方式思考?
  3. 假设我可以完成getTop20Stories(顾名思义,应该检索 20 条新闻,使用来自 的结果getTopStoryIDs,前 20 个元素的时间应该可以解决问题),我将如何从中检索数据?谁应该负责检索响应?虚拟机?分段?

提前致谢。

标签: androidkotlinmvvmretrofitrx-java

解决方案


您在 FlatMap 的正确轨道上。

这样的事情应该可以解决问题:

getTopStoryIDs().flatMap { storyId -> getStory(storyId) }

推荐阅读