Retrofit API call: How to make sure that value is not null after making api call?

耗尽温柔 提交于 2019-12-11 08:27:00

问题


I have below AuthenticationResponse model that I use for 3 api calls using retrofit2. If I make the verifyEmail call f.e. the JSON response body only contains an attribute for valid email (so something like {"validEmail": true} ). The other 2 calls only contain attributes for "resetSuccesful" or the other 4.

How can I make sure/check that when I receive the response to the verifyEmail call f.e. that it contains a non null value for validEmail??

Service:

interface AuthenticationService {

@POST("auth/checkEmail")
fun verifyEmail(@Body email: String): Call<AuthenticationResponse>

@POST("auth/login")
fun login(@Body loginCredentials: LoginCredentials): Call<AuthenticationResponse>

@POST("auth/resetPassword")
fun resetPassword(@Body email: String): Call<AuthenticationResponse>
}

Model:

data class AuthenticationResponse(

    val validEmail: Boolean? = null,

    val loginSuccess: Boolean? = null,
    val retriesLeft: Int? = null,
    val authToken: String? = null,
    val accountBlocked: Boolean? = null,

    val resetSuccesful: Boolean? = null)

edit: If i mock my server response to return f.e. responseCode = 200 - { "validEmail": null } and change validEmail type to Boolean (instead of Boolean?) Retrofit doesn't thrown any kind of exception (this is what i actually want) thus my model is giving me a false negative for my validEmail value..


回答1:


You should definitely consider @miensol's comment -- to have separate model objects for different API calls.

However, if that's not possible, you can use Sealed class.

sealed class AuthenticationResponse {

    data class EmailValidation(val validEmail: Boolean) : AuthenticationResponse()
    data class SomeSecondResponse(val loginSuccess: Boolean, ...) : AuthenticationResponse()
    data class SomeThirdResponse(val resetSuccessful: Boolean) : AuthenticationResponse()

}

fun handleResponse(response: AuthenticationResponse) {

    when (response) {
        is AuthenticationResponse.EmailValidation -> response.validEmail
        is AuthenticationResponse.SomeSecondResponse -> response.loginSuccess
        is AuthenticationResponse.SomeThirdResponse -> response.resetSuccessful
    }

}

Sealed class is enums on steroids -- it is enums with states. You have to create 3 classes for 3 responses which inherit from the sealed class AuthenticationResponse.

You have to create the specific class instance corresponding to the different API calls. To access the data, you can do type check and access the specific data. The above when example shows how to access all the types of response inside a function.

How can I make sure/check that when I receive the response to the verifyEmail call f.e. that it contains a non null value for validEmail??

Since you create the instance of only the specific classes and all the classes have only non-null properties, you don't have to worry about null.




回答2:


I would consider what @miensol mentioned in a comment, but if you wanted to add a check for this, you could do something like:

fun isEmailValid(authResponse: AuthenticationResponse): Boolean {
    return authResponse.validEmail ?: false
}

See Kotlin docs on Elvis Operator:

If the expression to the left of ?: is not null, the elvis operator returns it, otherwise it returns the expression to the right. Note that the right-hand side expression is evaluated only if the left-hand side is null.



来源:https://stackoverflow.com/questions/45842679/retrofit-api-call-how-to-make-sure-that-value-is-not-null-after-making-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!