Retrofit - pass two parameters - android

Link: "www.example.com/getnewcar/?car[color]={colorOfCar}&car[price]={priceOfCar}"
#GET(...)
fun getNewCar(
#Query("car[color]") color: String,
#Query("car[price]") price: String,
...
): Single<JSONApiObject>
I call this function like: b.getNewCar(carColor, carPrice)
URL query string ".." must not have replace block. For dynamic query parameters use #Query. What am I doing wrong? I looked at docs and they suggest using #Query. Can't find what's off tho.

#Query automatically generates the query part of the URL, so your #GET annotation should not include it.
Instead of #GET("www.example.com/getnewcar/?car[color]={colorOfCar}&car[price]={priceOfCar}") it should just be #GET("www.example.com/getnewcar/").

Related

How can i transcribe a URL to android studio? [duplicate]

I use Retrofit for most of my calls but in one of the cases, I have the full path provided in arguments. My URL is like this http://www.example.com/android.json. This URL is provided in full so I have to path it at runtime. I implement endpoint as suggested here
https://medium.com/#kevintcoughlin/dynamic-endpoints-with-retrofit-a1f4229f4a8d
but in the #GET I need to be able to put #GET(""). This does not work as I get an error saying I should provide at least one "/".
If I add the slash the URL becomes http://www.example.com/android.json/ and it does not work, the server returns forbidden. I also tried creating a custom GET interface similar to here https://github.com/square/retrofit/issues/458 but with GET and without providing a value method in the interface. Then I get another error saying value is missing.
Basically I need to be able to provide an empty or null value but retrofit does not allow that. How could I solve this problem? For now I am doing the JSON request manually but is there a way I could use retrofit for this case? I need to pass the full URL there is no way I can do endpoint http://www.example.com and #GET("/android.json").
Thanks
You can use #GET(".") to indicate that your url is the same as the base url.
#GET(".")
Observable<Result> getData(#Query("param") String parameter);
I've tried this approach, however didn't work for me.
Workaround for this issue is:
//Retrofit interface
public interface TestResourceClient {
#GET
Observable<Something> getSomething(#Url String anEmptyString);
}
//client call
Retrofit.Builder().baseUrl("absolute URL").build()
.create(TestResourceClient.class).getSomething("");
The downside of this solution is that you have to supply empty string in getSomething("") method call.
I face the same problem with Retrofit 2. Using #GET, #GET("") and #GET(".") not solved my problem.
According to the official document you can the same baseUrl and #GET argument.
Endpoint values may be a full URL.
Values that have a host replace the host of baseUrl and values also with a scheme replace the scheme of baseUrl.
Base URL: http://example.com/
Endpoint: https://github.com/square/retrofit/
Result: https://github.com/square/retrofit/
So in my case:
interface MyAPI {
#GET("http://www.omdbapi.com/")
suspend fun getMovies(
#Query("apikey") apikey: String,
#Query("s") s: String
): Response<MoviesResponse>
companion object {
operator fun invoke(): MyAPI {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://www.omdbapi.com/")
.build()
.create(MyAPI::class.java)
}
}
}

Add dynamic value in url retrofit

I have this below URL
URL TO CALL
In the interface I have as
#GET("storage/presigned-url?bucketName=files&key=payment-receipt/{fileName}&httpVerb=2&contentType=image/jpeg")
suspend fun fileUploadPathCheque(#Path("fileName") name: String): Response<String>
I want to replace the file name with some value
I am calling the function as
Api.fileUploadPathCheque(UUID.randomUUID().toString().plus(".jpg"))
I get the following exception
ava.lang.IllegalArgumentException: URL query string "bucketName=files&key=payment-receipt/{fileName}&httpVerb=2&contentType=image/jpeg" must not have replace block. For dynamic query parameters use #Query.
What shoudl be correct way of doing this?
The exception is self-explanatory, You need to use a query parameter for key. Something like
#GET("storage/presigned-url?bucketName=files&httpVerb=2&contentType=image/jpeg")
suspend fun fileUploadPathCheque(#Query("key") name: String): Response<String>`
and then call it appending payment-receipt/ to your passing parameter:
Api.fileUploadPathCheque("payment-receipt/" + UUID.randomUUID().toString().plus(".jpg"))
This should work for you.

How to use #Query in Retrofit? Android Kotlin

I'm currently trying to make an ApiInterface. I'm trying to manipulate API URL by using query. So far the URL I'm using is
https://api.themoviedb.org/3/search/movie?api_key={apiKey}&language=en-US&query={query}
The url above I'm trying to change the "query" So I created this interface:
#GET("3/search/movie?api_key=${BuildConfig.MOVIE_TOKEN}&language=en-US&")
fun getMovies(
#Query("query") query: String
): Call<SearchMovieResponse>
And it works well, but what if the case of the URL is this:
https://api.themoviedb.org/3/movie/{id}?api_key=7fad718afb38c7fe3fbe9da94e0d54e6
Where I'm trying to manipulate the {id}. Is the interface like this?
#GET("3/movie/{id}?api_key=${BuildConfig.MOVIE_TOKEN}")
fun getMovieById(
#Query("id") id: String
):Call<SearchDetailMovieResponse>
Please help me understand how to utilize the annotations to modify the API urls
To use the #Query properly in the case of the following URL:
https://api.themoviedb.org/3/movie/{id}?api_key=7fad718afb38c7fe3fbe9da94e0d54e6
You would need to write your interface as such
#GET("3/movie/{id}")
fun getMovieById(
#Path("id") id: String,
#Query("api_key") apiKey: String = BuildConfig.MOVIE_TOKEN
):Call<SearchDetailMovieResponse>
For more information refer to the documentation.
You can use #Path annotation for this.
#GET("3/movie/{id}?api_key=${BuildConfig.MOVIE_TOKEN}")
fun getMovieById(
#Path("id") id: String
):Call<SearchDetailMovieResponse>
Additional Info:
If you have parameter in middle of url and want to give dynamic value then use #Path annotation as you have id in middle of url.
e-g https://test-api/3/profile. 3 is param in middle of url in that case we use #Path
If you don't have parameter in middle of url and want to pass parameters at end of url with key value pair then better to use #Query
e-g https://test-api/profile?user_id=3 user_id is key value parameter in that case we use #Query.
Note: I am sharing as far as I understood.

How to resolve "#Url cannot be used with #PUT URL (parameter #1)"

I want to use #PUT and #Url together, but it throws an IllegalArgumentException
Edit
#PUT
fun editPost(
#Url() url: String = "xxxx/threads/{tid}",
#Path("tid") postId:Long,
#Body x: X
)
This answer is based on the assumption of you using Retrofit Library to make a API call. If that's not the case, my apologies and let me know so I can modify/remove the answer.
From what I've researched, you've probably implemented your interface method like the following:
#PUT("")
Call...
With this call, you should encounter java.lang.IllegalArgumentException: Missing either #GET URL or #Url parameteras you've not provided the addition parameter which is needed to complete the API call.
Therefore, you must keep the base URL in the mainActivity where you'll be making the call and route of the API within the bracket of the interface
#PUT("user/id")
or if you want to keep it blank as original, you must use #PUT(".") as this will declare that your final URL is the same as the Base URL provided in the mainActivity.
You were very close...
#PUT("xxxx/threads/{tid}"
fun editPost(
#Path("tid") postId: Long,
#Body x: X
)

Retrofit GET without a value in Android

I use Retrofit for most of my calls but in one of the cases, I have the full path provided in arguments. My URL is like this http://www.example.com/android.json. This URL is provided in full so I have to path it at runtime. I implement endpoint as suggested here
https://medium.com/#kevintcoughlin/dynamic-endpoints-with-retrofit-a1f4229f4a8d
but in the #GET I need to be able to put #GET(""). This does not work as I get an error saying I should provide at least one "/".
If I add the slash the URL becomes http://www.example.com/android.json/ and it does not work, the server returns forbidden. I also tried creating a custom GET interface similar to here https://github.com/square/retrofit/issues/458 but with GET and without providing a value method in the interface. Then I get another error saying value is missing.
Basically I need to be able to provide an empty or null value but retrofit does not allow that. How could I solve this problem? For now I am doing the JSON request manually but is there a way I could use retrofit for this case? I need to pass the full URL there is no way I can do endpoint http://www.example.com and #GET("/android.json").
Thanks
You can use #GET(".") to indicate that your url is the same as the base url.
#GET(".")
Observable<Result> getData(#Query("param") String parameter);
I've tried this approach, however didn't work for me.
Workaround for this issue is:
//Retrofit interface
public interface TestResourceClient {
#GET
Observable<Something> getSomething(#Url String anEmptyString);
}
//client call
Retrofit.Builder().baseUrl("absolute URL").build()
.create(TestResourceClient.class).getSomething("");
The downside of this solution is that you have to supply empty string in getSomething("") method call.
I face the same problem with Retrofit 2. Using #GET, #GET("") and #GET(".") not solved my problem.
According to the official document you can the same baseUrl and #GET argument.
Endpoint values may be a full URL.
Values that have a host replace the host of baseUrl and values also with a scheme replace the scheme of baseUrl.
Base URL: http://example.com/
Endpoint: https://github.com/square/retrofit/
Result: https://github.com/square/retrofit/
So in my case:
interface MyAPI {
#GET("http://www.omdbapi.com/")
suspend fun getMovies(
#Query("apikey") apikey: String,
#Query("s") s: String
): Response<MoviesResponse>
companion object {
operator fun invoke(): MyAPI {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://www.omdbapi.com/")
.build()
.create(MyAPI::class.java)
}
}
}

Categories

Resources