简体   繁体   中英

Manipulating complex url with retrofit in Kotlin?

I want to convert my ArticleDataProvider with fuel to Retrofit and I don't know how to manipulate the URLs.

I have an object Urls to get an random article or search for article:

object Urls {

private const val BaseUrl = "https://en.wikipedia.org/w/api.php"

fun getSearchUrl(term: String, skip: Int, take: Int): String {
    return BaseUrl + "?action=query" +
            "&formatversion=2" +
            "&generator=prefixsearch" +
            "&gpssearch=$term" +
            "&gpslimit=$take" +
            "&gpsoffset=$skip" +
            "&prop=pageimages|info" +
            "&piprop=thumbnail|url" +
            "&pithumbsize=200" +
            "&pilimit=$take" +
            "&wbptterms=description" +
            "&format=json" +
            "&inprop=url"
}

fun getRandomUrl(take: Int): String {
    return BaseUrl + "?action=query" +
            "&format=json" +
            "&formatversion=2" +
            "&generator=random" +
            "&grnnamespace=0" +
            "&prop=pageimages|info" +
            "&grnlimit=$take" +
            "&inprop=url" +
            "&pithumbsize=200"
}

}

And my ArticleProvider:

class ArticleDataProvider {

init {
    FuelManager.instance.baseHeaders = mapOf("User-Agent" to "Pluralsight Wikipedia")
}


fun search(term: String, skip: Int, take: Int, responseHandler: (result: WikiResult) -> Unit?) {
    Urls.getSearchUrl(term, skip, take).httpGet()
        .responseObject(WikipediaDataDeserializer()) { _, response, result ->

            try {

                //do something with result
                if (response.statusCode == STATUS_CODE) {
                    val (data, _) = result
                    responseHandler.invoke(data as WikiResult)

                }
            } catch (e: HttpException) {


            }
        }
}

fun getRandom(take: Int, responseHandler: (result: WikiResult) -> Unit?) {
    Urls.getRandomUrl(take).httpGet()
        .responseObject(WikipediaDataDeserializer()) { _, response, result ->
            try {
                //do something with result
                if (response.statusCode == STATUS_CODE) {
                    val (data, _) = result
                    responseHandler.invoke(data as WikiResult)
                }
            } catch (e: HttpException) {
                //    Log.e("error", e.message)
            }
        }
}


class WikipediaDataDeserializer : ResponseDeserializable<WikiResult> {
    override fun deserialize(reader: Reader) = Gson().fromJson(reader, WikiResult::class.java)!!
}

}

This is my interface for retrofit for the getRandom request

private const val BaseUrl = "https://en.wikipedia.org/w/"

interface ArticleProvider {

  @GET("api.php?action=query&format=json&generator=random&prop=pageimages|info&grnlimit={take}&inprop=url&pithumbsize=200")
  fun getRandom (@Query("grnlimit") take: Int) : Call<WikiResult>

companion object{
    fun create() : ArticleProvider {
        val retrofit = Retrofit.Builder()
            .baseUrl(BaseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        return retrofit.create(ArticleProvider::class.java)
    }
}

}

I should change all my values from Urls to Query in my GET or what should I do?

Well you can put query parameters which are not need to be changed straight to the URL. Then if you have some parameters which needs to be changed, then put those in function parameters like you have put one. You can also define every query parameter as function parameter with default value so it kind of documents the request better. You can declare the function parameter as nullable type so it wont go to the URL if it's set to null.

Here's a little example from your code:

@GET("api.php")
fun getRandom(
        @Query("action") action: String? = "query",
        @Query("format") format: String? = "json",
        @Query("generator") generator: String? = "random",
        @Query("prop") prop: String? = "pageimages|info",
        @Query("grnlimit") grnlimit: Int? = 0, // This can be left without default value so it must be given always
        @Query("inprop") inprop: String? = "url",
        @Query("pithumbsize") pithumbsize: Int? = 200) : Call<WikiResult>

Then you can call it in many different ways:

instanceToArticleProvider.getRandom() // Because every parameter has default values
instanceToArticleProvider.getRandom(grnlimit = 123) // You can use named params to change only one to URL
instanceToArticleProvider.getRandom("query", "json", "random", etc...)

And here's an example if you need only some of the paramteres to be changed and keep the constant parameters in URL:

@GET("api.php?action=query&format=json&generator=random&inprop=url&pithumbsize=200")
fun getRandom(
        // This can be left without default value so it must be given always
        @Query("grnlimit") grnlimit: Int? = 0) : Call<WikiResult>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM