Вызов ktor API с двумя ожидаемыми результатамиAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Вызов ktor API с двумя ожидаемыми результатами

Сообщение Anonymous »

Я создаю макет isuranceApp, и на этапе проверки otp мы должны ожидать два результата.
видите, я отправил запрос otp:
{
phoneNumber = "+101234123412",
secretKey = "abc"
}

и теперь пользователь может быть зарегистрированным пользователем, и в этом случае ответ будет:
{
userId = "000",
token = "abc101"
}

и если это не зарегистрированный пользователь, мы получим ответ:
{
message = "code is correct",
opCode = "xxx"
}

ну, как вы видите, есть два ожидаемых результата, и я не знаю, как с этим справиться с моей архитектурой, вставленной наполовину:
покажу вам процесс от viewModel до моей httpClientFactory
viewModel:
class OTPViewModel(
private val repository: AuthRepository
): ViewModel() {

private fun verify() {

viewModelScope.launch {
state = state.copy(isLoggingIn = true)

val result = repository.loginOTP(
otpCode = state.otpCode.text.toString().trim()
)

state = state.copy(isLoggingIn = false)

when(result) {
is Result.Error -> {
if (result.error == DataError.Network.CONFLICT) {

} else {
eventChannel.send(OTPEvent.Error(result.error.asUiText()))
}
}
// handle the secreteKey mechanism in sessionStorage
is Result.Success -> {

}
}
}
}

}

класс результата:
sealed interface Result {

data class Success(val data: D): Result
data class Error(val error: E): Result
}

inline fun Result.map(map: (T) -> R): Result {
return when(this) {
is Result.Error -> Result.Error(error)
is Result.Success -> Result.Success(map(data))
}
}

fun Result.asEmptyResult(): EmptyResult {
return map { }
}

typealias EmptyResult = Result

authRepository:
class AuthRepositoryImpl(
private val httpClient: HttpClient,
val sessionStorage: SessionStorage
): AuthRepository {
override suspend fun loginPhoneNumber(phoneNumber: String): EmptyResult {
val result = httpClient.post(
route = "/req",
body = LoginPhoneNumberRequest(
phoneNumber = phoneNumber
)
)

if (result is Result.Success) {
sessionStorage.setSecretKey(
secretKey = result.data.secretKey
)
}

return result.asEmptyResult()
}

override suspend fun loginOTP(otpCode: String): EmptyResult {
TODO("Not yet implemented")
}
}

httpClient:
suspend inline fun HttpClient.post(
route: String,
body: Request
): Result {

return safeCall {
post {
url(constructRoute(route))
setBody(body)
}
}
}

suspend inline fun safeCall(execute: () -> HttpResponse): Result {
val response = try {
execute()
} catch (e: UnresolvedAddressException) {
e.printStackTrace()
return Result.Error(DataError.Network.NO_INTERNET)
} catch (e: SerializationException) {
e.printStackTrace()
return Result.Error(DataError.Network.SERIALIZATION)
} catch (e: Exception) {
if (e is CancellationException) throw e
e.printStackTrace()
return Result.Error(DataError.Network.UNKNOWN)
}

return responseToResult(response)
}

suspend inline fun responseToResult(response: HttpResponse): Result {
return when (response.status.value){
in 200..299 -> Result.Success(response.body())
401 -> Result.Error(DataError.Network.UNAUTHORIZED)
408 -> Result.Error(DataError.Network.REQUEST_TIMEOUT)
409 -> Result.Error(DataError.Network.CONFLICT)
413 -> Result.Error(DataError.Network.PAYLOAD_TOO_LARGE)
429 -> Result.Error(DataError.Network.TOO_MANY_REQUESTS)
in 500..599 -> Result.Error(DataError.Network.SERVER_ERROR)
else -> Result.Error(DataError.Network.UNKNOWN)
}
}

fun constructRoute(route: String): String {
return when {
route.contains(BuildConfig.BASE_URL) -> route
route.startsWith("/") -> BuildConfig.BASE_URL + route
else -> BuildConfig.BASE_URL + "/$route"
}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... d-outcomes
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»