android10 / Android-CleanArchitecture-Kotlin

This is a movies sample app in Kotlin, which is part of a serie of blog posts I have written about architecting android application using different approaches.
https://fernandocejas.com/2018/05/07/architecting-android-reloaded/
4.69k stars 935 forks source link

Declare @Body data class in Api internal interface #21

Open UriAbadAtabix opened 6 years ago

UriAbadAtabix commented 6 years ago

I want to make a data class in order to send data via post...but internal declaration of Api interface not allows me to archieve this. If I remove internal declaration, it works, but Repository class shouldn't have to fill an ApiParams class.....

internal interface LoginApi {
    companion object {
        private const val LOGIN = "login"
        private const val PARAM_ACCOUNT = "account"
        private const val PARAM_EMAIL = "email"
        private const val PARAM_PASSWORD = "password"
    }

    @POST(LOGIN) fun login(@Body params: LoginParams): Call<LoginEntity>
    data class LoginParams(
            @SerializedName(PARAM_ACCOUNT) private val account: String,
            @SerializedName(PARAM_EMAIL) private val email: String,
            @SerializedName(PARAM_PASSWORD) private val password: String
    )

}
jmcaldera commented 6 years ago

Why don't you pass these params to the remoteDataSource which will be responsible for creating theLoginParamsclass and pass it to the service to perform the POST request?

I don't see the problem of the Repository creating the LoginParams instance tho.

UriAbadAtabix commented 6 years ago

Cause remoteDataSource already have an implementation of LoginApi. I didn't know how to expose LoginParams class to remoteDataSource through his implementation.

aaghan commented 4 years ago

@UriAbadAtabix Have you looked onto the Either and Usecase class?

for reference, I've used this for post api class DoLogin

@Inject constructor(private val featureAuthRepo: FeatureAuthRepo):UseCase<LoginResponse,DoLogin.Params>(){

    data class Params(val mac:String, val pass:String)

    override suspend fun run(params: Params): Either<Failure, LoginResponse> = featureAuthRepo.doLogin(params.mac,params.pass)
}

I've sent params object

Zhuinden commented 4 years ago

It's so much easier if UseCase class doesn't exist, then you don't have to add a Params object just to have a function that has more than 1 argument.

Not to mention, UseCase does nothing except call featureAuthRepo, so why even have the featureAuthRepo at all.

aaghan commented 4 years ago

@Zhuinden Yes I agree on you, but for the startup on going through clean-architecture and to find all the functionalities without going through all the project, I found it easier to understand and hence kept this more class for each one.