Mugur
Mugur

Reputation: 1029

format @Query parameter - Retrofit 2

I switched to using Retrofit2 and everything is nice and clean... But there is a service call that requires that a query parameter be inside a regular expression(don't ask me why, I already asked for it to be changed).

Here is how my method looks like:

@GET("prod/search")
fun searchProducts(@Query("q") q: String?): Call<Array<Product>>

If I call searchProducts("lala"), the query will look like: prod/search?q=lala, but I need it to look like prod/search?q=(?i)\\Qlala\\E

Is there a simple way to format the query parameter to do that?

Upvotes: 3

Views: 1398

Answers (2)

tynn
tynn

Reputation: 39843

You could use the statical typing for your advantage. From the @Query documentation:

Values are converted to strings using Retrofit.stringConverter(Type, Annotation[]) (or Object.toString(), if no matching string converter is installed) and then URL encoded.

You'd only have to create a simple wrapper of String and override toString():

data class RegularString(val value: String) {
    override fun toString() = "(?i)\\\\Q$value\\\\E"
}

Then use RegularString as a query parameter:

@GET("prod/search")
fun searchProducts(@Query("q") q: RegularString): Call<Array<Product>>

Upvotes: 2

Eduard Kornev
Eduard Kornev

Reputation: 584

Think, you can use only another method. Something like this:

    searchProducts(prepareParameter("lala"))

    fun prepareParameter(query: String) = "(?i)\\\\Q" + query + "\\\\E"

Also you can use Interceptor. But it would be call in every request, so I recommend you use first variant.

object : Interceptor {
            override fun intercept(chain: Interceptor.Chain?): Response {
                val original = chain!!.request()
                val originalUrl = original.url()
                if (originalUrl.encodedPath().contains("prod/search")) {
                    val value = originalUrl.queryParameter("q")
                    val newUrl = originalUrl.newBuilder()
                            .setQueryParameter("q", "(?i)\\\\Q$value\\\\E")
                            .build()

                    val request = original.newBuilder().url(newUrl).build()
                    return chain.proceed(request)
                }

                return chain.proceed(original) 
            }
        }

And in your retrofit builder:

val client = new OkHttpClient.Builder()
                 .addInteceptor(yourInterceptor)
                 .build()
val retrofit = Retrofit.Builder().client(client).build()

Upvotes: 1

Related Questions