skydoves/sandwich

How do I use Sandwich if the json is not a standard?

StrikeZXA opened this issue · 8 comments

How do I use Sandwich if the json is not a standard?
The response json is ....
success
{"code":0,"msg":"success", "data": {}}

fail
{"code":-1,"msg":"fail"}

Hi, could you let me know what kind of serialization library do you use? e.g., Gson, Moshi

Gson or Moshi ,I can use them all

I think this issue is related to the usage of Gson or Moshi.
Because converting json to object is their works.

That way I can't request in Sandwich like Pokedex App.
In a sense,I'm going to have more trouble using Sandwich.
I don't want to every time in the response. SuspendOnSuccess conversion operation.
Does Sandwich support directly returning the data field?

Now MyApp request like this
`viewModelScope.launch {
val result = appDataManager.requestVerifyCode(itac, receiveTarget)
if (result is Result.Success) {

   } else if (result is Result.Error) {
      
  }

}`

suspend fun requestVerifyCode(itac: String, receiveTarget: String): Result<VerifyCodeEntity> { return safeApiCall( call = { executeResponse(apiService.requestVerifyCode(itac,receiveTarget)) }, errorMessage = "Network Error" ) }

`
data class LazyEntity(val code: Int, val msg: String, val data: T)

suspend fun safeApiCall(call: suspend () -> Result, errorMessage: String): Result {
return try {
call()
} catch (e: Exception) {
// An exception was thrown when calling the API so we're converting this to an IOException
Logger.i("Exception = ${e.message}")
Result.Error(IOException(errorMessage, e))
}
}

suspend fun executeResponse(
response: LazyEntity,
successBlock: (suspend CoroutineScope.() -> Unit)? = null,
errorBlock: (suspend CoroutineScope.() -> Unit)? = null
): Result {
return coroutineScope {
if (response.code == 0) {
errorBlock?.let { it() }
Logger.i("Exception = ${response.msg}")
Result.Error(IOException(response.msg))
} else {
successBlock?.let { it() }
Result.Success(response.data)
}
}
}`

@Headers("Content-Type: application/json") @POST("db-api/general/sms/verify_code") suspend fun requestVerifyCode( @Field("itac") type: String, @Field("receiveTarget") receiveTarget: String, ): LazyEntity<VerifyCodeEntity>

`sealed class Result {

data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception,val code:Int = 404) : Result<Nothing>()

override fun toString(): String {
    return when (this) {
        is Success<*> -> "Success[data=$data]"
        is Error -> "Error[exception=$exception]"
    }
}

}`

So I think it's going to be more troublesome to use Sandwich in my app

Hi, sorry I don't understand what you want to resolve.
As I understand, you can handle the response based on its type like the below?

val response = disneyService.fetchDisneyPosterList()
when (response) {
  is ApiResponse.Success -> // do something
  is ApiRespnse.Error.Failure -> // 
  is ApiResponse.Error.Exception -> //
}

Also, you can use like the below using if statement.

val response = disneyService.fetchDisneyPosterList()
if (response is ApiResponse.Success) {
  // do something
}
ldileh commented

hello @skydoves, i had a case like this. the endpoint return the json with template like @dempsey. my problem is when I created the base class for the response it's working. but when I'm trying to use runAndRetry extension, it's show the warning :
Type mismatch. Required: Any Found: BaseResponse<TokenResponseModel>?

Screenshot 2023-12-01 135918

but when i change the body without the BaseResponse model, the 'runAndRetry ' method working well without the warning show up.

how do i solve this?

this is my base response model class
@Keep @Serializable data class BaseResponse<T>( @SerializedName("error") val error: ErrorModel? = null, @SerializedName("success") val success: Boolean?, @SerializedName("data") val data: T? = null )

ldileh commented

BTW, this dependency is aweseom! it's really helped me with the development process that I was doing

Hey @ldileh, what is the return type of the otpVerification method? You should return non-nullable type for using it.