Я создаю макет 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
Вызов ktor API с двумя ожидаемыми результатами ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1731532178
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"
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79186686/ktor-api-call-with-two-expected-outcomes[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия