1

I'm trying to learn about clean architecture. I've a question.According to this article

Making a network request is one of the most common tasks an Android app might perform. The News app needs to present the user with the latest news that is fetched from the network. Therefore, the app needs a data source class to manage network operations: NewsRemoteDataSource.To expose the information to the rest of the app, a new repository that handles operations on news data is created: NewsRepository.

https://developer.android.com/jetpack/guide/data-layer#create_the_data_source

I found lots of example like below. Why they are manage network operations in repository class. Android says we should use a DataSource Class. Can you explain which works needs to be done in repository class? Maybe with some examples.

class WordInfoRepositoryImpl(
private val api: DictionaryApi,
private val dao: WordInfoDao
): WordInfoRepository {

override fun getWordInfo(word: String): Flow<Resource<List<WordInfo>>> = flow {
    emit(Resource.Loading())

    val wordInfos = dao.getWordInfos(word).map { it.toWordInfo() }
    emit(Resource.Loading(data = wordInfos))

    try {
        val remoteWordInfos = api.getWordInfo(word)
        dao.deleteWordInfos(remoteWordInfos.map { it.word })
        dao.insertWordInfos(remoteWordInfos.map { it.toWordInfoEntity() })
    } catch(e: HttpException) {
        emit(Resource.Error(
            message = "Oops, something went wrong!",
            data = wordInfos
        ))
    } catch(e: IOException) {
        emit(Resource.Error(
            message = "Couldn't reach server, check your internet connection.",
            data = wordInfos
        ))
    }

    val newWordInfos = dao.getWordInfos(word).map { it.toWordInfo() }
    emit(Resource.Success(newWordInfos))
}

}

Tunahan
  • 194
  • 1
  • 11

1 Answers1

1

Here is a great article explaining the difference between a DAO and a Repository. https://www.baeldung.com/java-dao-vs-repository

I would consider the API as an impromptu DAO for remote databases. Since you don't have access to the remote database structure, it will be the closest thing you are going to get to a DAO.

This Repository is responsible for collating the two data sources. The DAO is the local one and the API is the remote one.

It looks like it retrieves the local data and emits it. It then tries to retrieve the remote data to update the local data. It finally then re-emits the local data.

I think the example you posted falls within the normal responsibilities of a Repository, as per the article.

avalerio
  • 2,072
  • 1
  • 12
  • 11
  • If I create a RemoteDataSource class and implement network functions in it. Does it be more clearly ? The point I can't understand is if repository is a bridge between data layer and ui layer why api request is calling in repository class instead of datasource class in this example? @avalerio – Tunahan Jan 23 '22 at 10:35
  • I guess you could have a `RemoteDataSource` abstraction that handles those networking exceptions in a standardized way. But that depends on how much you need that in your project, The `API` call is part of your data layer, with an added restriction of networking exceptions. Again a `Repository` combines multiple data sources. The `API` is a data source and your `API` isn't requiring you to add networking functions, its only requiring you to handle exceptions, those exceptions just happen to be `IO` and network related. – avalerio Jan 23 '22 at 16:48
  • You say retrofit and it's functions they are already kind of a datasource class. That's why i don't need a RemoteDataSource class again am i right? @avalerio – Tunahan Jan 23 '22 at 21:51
  • Yes I would say that is true. There may come a time when you need to abstract away the `DataSources` but looking at the given example I would say that is fine, how it is. – avalerio Jan 23 '22 at 22:44
  • When can i need to DataSources class can you give me a simple example or situation without my example @avalerio . – Tunahan Jan 23 '22 at 23:49
  • That is more of a general question on when to use inheritance and interfaces. Any time you want to swap out implementations of the `DAO` or `API`. For example if you made a `BaseRepository` class, if you want to use it for all `DAOs` and `APIs` it will need to handle them in a polymorphic fashion. Here is answer they may help you. https://stackoverflow.com/questions/1686174/when-should-one-use-interfaces – avalerio Jan 24 '22 at 00:40