I want to customizer my endPoint using Retrofit2 on Android but I have a doubt.
If I do that:
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(#Query("one") String one, #Query("two") String two,
#Query("key") String key)
My endPoint could be like this:
//-> https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434
I'm working with this endPoint:
// -> https://example.com/third-party-public/categories/category_id.json
If I use the same ideia as I explained above the result can be is:
#GET("/third-party-public/categories/")
Observable<List<Category>> getCategoryDetail(#Query(".json") String category_id);
The result could be:
// -> https://example.com/third-party-public/categories/.json=1
But I want that result
// -> https://example.com/third-party-public/categories/1.json
How can I setting my #query for get that result?
#GET("/third-party-public/categories/{category_id}.json")
Observable<List<Category>> getCategoryDetail(#Path("category_id") String category_id);
If you set a request with query it sets as query param '?'.
If the result you want is that you simply use it as in path:
#GET("Search/{fileUri}")
Call<Products> getProducts(#Path("fileUri") String fileUri);
You get the value it as "1.json".
I'm trying to call the youtube API which looks like this:
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=10&playlistId=UU4MePVEgmibN-KAMF4-heTA&key=<KEY>
But I'm getting the error "URL query string" part = snippet {maxResults} {playlistId} {key} "must not have replace block.For dynamic query parameters use #Query." Am I doing something wrong ?? I'm currently doing so:
#GET("playlistItems?part=snippet{maxResults}{playlistId}{key}")
Call<PlaylistItemListResponse> getPlayListItemsList(#Query("maxResults") int maxresults, #Query("playlistId") String playlistId, #Query("key") String key);
You need to fix the URL in the #GET Annotation.
Please check the Retrofit Documentation at: https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/Query.html
Simple Example:
#GET("/friends")
Call friends(#Query("page") int page);
Calling with foo.friends(1) yields /friends?page=1.
Probably better for your case is using a Query Map.
I'm looking for way to add an int array (e.g [0,1,3,5]) as parameter in a GET request with retrofit 2. Then, the generated url should be like this : http://server/service?array=[0,1,3,5]
How to do this ?
Just add it as a query param
#GET("http://server/service")
Observable<Void> getSomething(#Query("array") List<Integer> array);
You can also use int[], or Integer... as a last param;
You need to name your query param with an array syntax like so:
#GET("http://server/service")
Observable<Void> getSomething(#Query("array[]") List<Integer> array);
The syntax itself will vary by the backend technology being used, however not including the brackets "[]" will normally be interpreted as a single value.
For example, using array=1&array=2 will generally be interpreted by backends as only array=1 or array=2 instead of array=[1,2].
I have finally founded a solution by using Arrays.toString(int []) method and by removing spaces in this result because Arrays.toString return "[0, 1, 3, 5]". And my request method looks like this
#GET("http://server/service")
Observable<Void> getSomething(#Query("array") String array);
I faced a similar problem and had to do a couple of things to reach the acceptable form (as asked in the question).
Converted an ArrayList to String
arrayList.toString().replace(" ", "")
In RetroFit method, I changed the Query param which accepts the ArrayList above to as follows:
#Query(value = "cities", encoded = true)
This ensures that the brackets and commas are not URL encoded.
Using toString didn't work for me.
Instead, TextUtils.join(",", ids) does the trick.
Don't forget to mark the Query with encoded = true.
Well this did the trick for me
Step 1 :
In StateServce.kt
#GET("states/v1")
fun getStatesByCoordinates(#Query("coordinates", encoded = true) coordinates: String) : Call<ApiResponse<List<State>>>
Step 2
While calling from repository
val mCoordinate : List<Double> = [22.333, 22.22]
mStateService?.getStatesByCoordinates(mCoordinate.toString().replace(" ", ""))!!
Use Iterable to encapsulate the integer list, or use a two-dimensional integer array.
How to define:
public interface ServerService {
#GET("service")
Call<Result> method1(#Query("array") Iterable<List<Integer>> array);
#GET("service")
Call<Result> method2(#Query("array") Integer[][] array);
}
How to use:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://server/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ServerService service = retrofit.create(ServerService.class);
// Use the first method.
List<Integer> data1 = Arrays.asList(0,1,3,5);
Iterable array1 = Arrays.asList(data1);
Call<Result> method1Call = service.method1(array1);
// Use the second method.
Integer[] data2 = new Integer[]{0,1,3,5};
Integer[][] array2 = new Integer[][]{data2};
Call<Result> method2Call = service.method2(array2);
// Execute enqueue() or execute() of method1Call or method2Call.
Please refer to the code ParameterHandler.java of Retrofit2 for the reason why the way can solve the problem.
You can pass the value as below
In Repository
getApiResponse(arrayOf(0,1,3,5).contentToString())` In Kotlin.
#GET("http://server/service")
suspend fun getApiResponse(#Query("array") array: String): Response
It will work.
I am using yahoo weather api and getting result using this link:
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22london%22)&format=json
Now I want to using this url with retrofit. So please tell me how to change the city by passing query.
Thank you
It would end up being something like this:
public interface WeatherService {
#GET("v1/public/yql")
Call<String> getWeather(#Query("q") String query);
}
Then create the object like this:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://query.yahooapis.com")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
WeatherService wService = retrofit.create(WeatherService.class);
And run it like this:
String query = "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"Leeds\")&format=json";
Call<String> weather = wService.getWeather(query);
try {
Response<String> resp = weather.execute();
You should change the ConverterFactory to json and properly parse the weather output.
I have not tested this, just giving you an idea of how to use the Retrofit query.
If I understand well, you are looking for a way to include a given city to the url. Here is a sample code on how to do so. In the example the variable city could take any given city name.
var city = "london";
var query = "select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22"+ city +"%22)&format=json"
Update:
then you could concatenate the query to the base url like this :
var baseurl = "https://query.yahooapis.com/v1/public/yql?q=" + query;
Hi all i call below URL using Retrofit
https://api.stackexchange.com/2.2/me?key=gQJsL7krOvbXkJ0NEI((&site=stackoverflow&order=desc&sort=reputation&access_token=HM*22z8nkaaoyjA8))&filter=default
and for that i created Interface RestInterface
//get UserId
#GET("/me&site=stackoverflow&order=desc&sort=reputation&access_token={access_token}&filter=default")
void getUserId(#Query("key") String apikey,#Path("access_token") String access_token,Callback<UserShortInfo> cb);
When i do this it always add key at the end of the URL(Output below).
I added #Query("key") as Query Parameter becoz it's dynamic.
http://api.stackexchange.com/2.2/me&site=stackoverflow&order=desc&sort=reputation&access_token=p0j3dWLIcYQCycUHPdrA%29%29&filter=default?key=gQJsL7krOvbXkJ0NEI%28%28
and that's the wrong. I got HTTP 400. Also here (( and )) converted into %28%28 and %29%29
Please help me how to make
https://api.stackexchange.com/2.2/me?key=gQJsL7krOvbXkJ0NEI((&site=stackoverflow&order=desc&sort=reputation&access_token=HM*22z8nkaaoyjA8))&filter=default
in Retrofit. I want it add #Query parameter in between URL. not at the end of the URL
Don't put query parameter inside the URL only the path parameter you can add
#GET("/me?site=stackoverflow&order=desc&sort=reputation&filter=default)
void getUserId(#Query("key") String apikey,#Query("access_token") String access_token,Callback<UserShortInfo> cb);
#Query("access_token") --> given key and value will come query URL
While sending request your URL form will like below
/me?key=?site=stackoverflow&order=desc&sort=reputation&filter=default&"your_value"&access_token="your_value"
obviously instead
#GET("/me&site=stackoverflow&order=desc&sort=reputation&access_token={access_token}&filter=default")
void getUserId(#Query("key") String apikey,#Path("access_token") String access_token,Callback<UserShortInfo> cb);
you should use
#GET("/me?site=stackoverflow&order=desc&sort=reputation&filter=default")
void getUserId(#Query("key") String apikey,#Query("access_token") String access_token,Callback<UserShortInfo> cb);
the chanege is /me& to /me? ... (and second is to use access_token as Query param too, not as a Path)
edit more explanations:
After parsing url which looks like (me&)
scheme:host/me&blablalbal=blalbla&blabla=blabla
the path is
me&blablalbal=blalbla&blabla=blabla
and there is no query paramas at all ... so adding params end with adding ?param=value at the end
but with (me?)
scheme:host/me?blablalbal=blalbla&blabla=blabla
the path is
me
and there are already some query parameters ... so addin new end with adding ¶m=value at the end :)