Data Layer

As the name suggests, it contains our data. API interfaces, databases, and Repository Implementation reside in this layer.

The Data Layer in clean architecture assumes the role of handling data flow and retrieving information from diverse sources like databases, web services, and files.

OneCall

OneCall is an object that can make requests to endpoints, OneCall uses Retrofit which is modified to make the code shorter and easier to use.

Api Service

The first step is to create an interface class to create a service that calls the endpoint, this service uses the built-in functions of retrofit.

interface MovieApi {

    @GET("movie/{id}")
    suspend fun getDetailMovie(
        @Path("id") id: Int
    ): Response<MovieDetailResultResponse>

}

Repository

Repository is a class that abstracts access to multiple data sources. It serves as an interface between the domain layer and the data layer, providing a clean API for data access.

interface MovieRepository {
    suspend fun getDetailMovie(id: Int): Flow<Resource<MovieDetailResultResponse>>
}

Data Store

A data store is a component that provides access to a specific data storage mechanism, such as a local database, remote server, or file system. Data sources are responsible for performing operations such as fetching data, saving data, and deleting data.

You can use enqueue inside suspend function, the function that uses enqueue is a coroutine flow.

For Example:

class MovieDataStore(
    private val api: MovieApi,
    private val errorParser: ErrorParser,
) : MovieRepository {

    override suspend fun getDetailMovie(id: Int): Flow<Resource<MovieDetailResultResponse>> = flow {
        OneCall.enqueue(
            id,
            errorParser::convertGenericError,
            api::getDetailMovie,
            onEmit = { emit(it) }
        )
    }.flowOn(Dispatchers.IO)

}

OneCall can currently only accept 5 parameters outside of errorParser, webService and onEmit which are data type and data class.

Post Data Using OneCall

Just like fetching data to the API, you can use enqueue and pass in parameters that are data classes or other data types.

For Example:

override suspend fun login(body: LoginRequest): Flow<Resource<ResponseWrapper<LoginResponse>>> =
    flow {
        OneCall.enqueue(
            body,
            error::convertGenericError,
            login::login,
            onEmit = { data -> emit(data) })
    }.flowOn(Dispatchers.IO)

Last updated