I’m trying to properly design an application according to clean architecture, but I’m struggling to determine on which layer (data/domain) to implement certain logic. In my application, there’s a feature that displays data (user contacts) which can be either set locally in settings or retrieved through an API. Which version to show the user depends on other settings and the app’s usage mode, for example, the API returns data, but the user has set a preference for using local data in the app’s settings. On which layer should I implement the logic for choosing the data source?
Let’s say there is a GetUserContactsUseCase in the domain.
Then, as I understand it, there are several approaches:
Approach 1
UserRepository, which contains 2 sources:
LocalData – contains all local settings, such as contact data and priority settings.
RemoteData – loads and caches data from the API.
GetUserContactsUseCase accesses RemoteData and LocalData (which apparently need to be renamed to RemoteDataRepository and LocalDataRepository), determines the priorities, and then fetches the data from them. The downside of this solution is that it seems the Repository should be determining the data source itself.
Approach 2
UserRepository independently determines the priority. This maintains encapsulation of layers, but in this case, UserRepository contains business logic that seems like it should be in a UseCase, not a repository. It is also not possible to call a UseCase from a repository. One solution seems to be writing a separate UseCase to determine the source of UserContacts and pass its result (e.g., UserContactFetchMode) to UserRepository. This UseCase still leads back to approach 1 as it will need the same LocalData and RemoteData.
Question:
Please advise on the best way to organize this.
I’m not sure if it’s relevant to my question, but I suspect there is some confusion in the level of function distribution among the Repositories themselves, for instance, instead of having a single LocalPreferences, it might be necessary to create several instances, like LocalUserData, LocalPreferencesData, etc.