Home > Back-end >  How can I create a model for this API (Kotlin-Retrofit)?
How can I create a model for this API (Kotlin-Retrofit)?

Time:09-24

I'm using https://www.api-football.com to get football countries and leagues, Json response for countries is like this:

{
"get": "countries",
"parameters": [],
"errors": [],
"results": 164,
"paging": {
    "current": 1,
    "total": 1
},
"response": [
    {
        "name": "Albania",
        "code": "AL",
        "flag": "https://media.api-sports.io/flags/al.svg"
    },
    {
        "name": "Algeria",
        "code": "DZ",
        "flag": "https://media.api-sports.io/flags/dz.svg"
    },
    {
        "name": "Andorra",
        "code": "AD",
        "flag": "https://media.api-sports.io/flags/ad.svg"
    },
    

    ...

I tried to create a model like this:

Here is the CountryData data class:

data class CountryData (
val code: String,
val flag: String,
val name: String
)

And here is the Country data class which uses CountryData and use them in a list:

data class Country(
val results : List<CountryData>
)

But those models give me some errors: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was NUMBER at line 1 column 61 path $.results

And I think that's because of the api response type is not a list of CountryData.

So if that's the problem, I want to get only the part after "response": [ ... But I don't know how to do this.

If you think another problem causes this error please let me know.

By the way, here is the api interface:

interface FootballApi {

@Headers("X-RapidAPI-Key: $API_KEY")
@GET(GET_COUNTRIES)
suspend fun getCountries() : Response<Country>
}

And here is my Retrofit Instance :

object RetrofitInstance {

val api: FootballApi by lazy {
    Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(FootballApi::class.java)
}
}

CodePudding user response:

I solved this problem by adding other data models to my project. Here is the Country data class:

data class Country(
val code: String,
val flag: String,
val name: String
)

Here is the CountryResponse data class:

data class CountryResponse (
val get: String,
val parameters: List<Any>,
val errors: List<Any>,
val results: Int,
val paging: Paging,
val response: List<Country>
)

Here is the Paging data class:

data class Paging(
val current: Int,
val total: Int
)

And now I can get the country list by response.body()!!.response

CodePudding user response:

The problem you had in the first place is that parameter names in your model do matter! At first you tried to unmarshal the JSON data into the wrong model:

data class Country(
val results : List<CountryData>
)

The JSON field with all the countries in it has the name response like this:

"response": [
    {
        "name": "Albania",
        "code": "AL",
        "flag": "https://media.api-sports.io/flags/al.svg"
    },
    ...

So if you use the same attribute in your model it should work without the need of adding all the other attributes (which you probably don't need) to your model:

data class Country(
val response: List<CountryData>
)
  • Related