about Retrofit get and post methods parameters - android

I read retrofit is good for client server communication.
In this I have some doubts.
#GET("/group/{id}/users")
List<User> groupList(#Path("id") int groupId);
In get method what is group, id, users, and what is groupList(#Path("id") int groupId). What will it do exactly?

When you build a new adapter for your interface with Retrofit you specify some server as endpoint. Let's say your endpoint is http://www.example.com. After that, when you execute groupList method, Retrofit will send a GET request to the http://www.example.com/group/{id}/users, where {id} placeholder will be replaced with a value you provided with groupId parameter during method call. So, this default parameter of GET annotation is just a path that should be appended to the server name and the value for placeholder is provided at the runtime.

/group/{id}/users this your GET request url (BASE_URL + Your GET url) where your id will be replaced with groupId passed in your groupList(#Path("id") int groupId); method.
Now your final request GET URL will be
BASE_URL + /group/{your groupId passed in method}/users
finally response from server will be parsed to List<User> and returned.

Related

Android: Path parameters in HTTP get method by retrofit

I have this api link:
http://www.xxxx.com/?apikey=mykey&i=tt036543
Now by retrofit I am trying to call this api with GET method so I can create this interface:
#GET("/?apikey=mykey&i={movie_id}")
Call<MovieDetailEntity> getSearchedMovie(#Path("movie_id") String id);
But I got this error:
java.lang.IllegalArgumentException: URL query string "apikey=mykey&i={movie_id}" must not have replace block. For dynamic query parameters use #Query.
for method BatmanService.getSearchedMovie
If I use this Query :
#GET("/?apikey=mykey&i=")
Call<MovieDetailEntity> getSearchedMovie(#Query("movie_id") String id);
Then the link changes to :
http://www.xxxx.com/?apikey=mykey&i=&movie_id=tt036543
How can I call this api?
If I remember well once you use #query you should not set the variable at the url. It will use the string inside the #query annotation as the variable name.
This should work:
#GET("/?apikey=mykey")
Call<MovieDetailEntity> getSearchedMovie(#Query("i") String id);
And also this, if you want to pass your api key as well:
#GET("/")
Call<MovieDetailEntity> getSearchedMovie(#Query("apikey") String mykey,
#Query("i") String id);
The ? and & are automatically added for you.

How to perform delete api in retrofit

Here is the url for the code for which delete operation is required
URL-http://something.com/Api/remove_player.php
These are the Parameters for request params - user_id, id
How to use delete API for these params?
This is the Interface class in which there is usage of #Path -
public interface ApiDeleteInterface {
#DELETE("/Api/remove_player.php")
Call<Response> getResponse(#Path("user_id") int user_id
,#Path("id") int id
);
}
#DELETE annotation is used for detlete api. What shoul we use in response inside call?
Is this the correct way to make interface ?Should the code use path or any other annotation?
There is DELETE PLAYER API which has url and params below
URL - http://something.com/Api/remove_player.php
Parameters - user_id, id.
How to make delete API using retrofit?
Use #Query instead of #Path to set url parameters.
public interface ApiDeleteInterface {
#DELETE("/Api/remove_player.php")
Call<Response> getResponse(#Query("user_id") int user_id, #Query("id") int id);
}
The resulting url would look like: /Api/remove_player.php?user_id=1&id=2
#Path is a named replacement for a value in the URL. If you want to use #Path, your URL would need to update to something like:
public interface ApiDeleteInterface {
#DELETE("/Api/user_id/{user_id}/id/{id}/remove_player.php")
Call<Response> getResponse(#Path("user_id") int user_id, #Path("id") int id);
}
check out the docs
https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/Query.html
https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/Path.html

How to add Authorization header with Retrofit2 + RxJava

I want to perform request using Retrofit2 and RxJava
public static Observable<Post> getPostsAround(Location location, int offset, int limit) {
if(api==null) {
new RestService(); //initialize API in constructor
}
return api.getPostsAround(location.getLatitude(),location.getLongitude(),offset,limit)
.flatMapIterable(posts -> posts); //transform Observable<List<Post>> to Observable<Post> which emits posts onNext
}
I tried #Headers("Authorization: code) annotation, but I don't know how to change "code" in runtime.
I have found an answer:
A request Header can be updated dynamically using the #Header annotation. A corresponding parameter must be provided to the #Header. If the value is null, the header will be omitted. Otherwise, toString will be called on the value, and the result used.
#GET("user")
Call<User> getUser(#Header("Authorization") String authorization)

How to use #Query in URL in Retrofit?

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 &param=value at the end :)

Retrofit: how fix "only one http method is allowed. found: get and get"?

I have that structure for request.
Request getTransportByStation work perfectly.
But I get exception java.lang.IllegalArgumentException: TransportWebService.getTransportByRoute: Only one HTTP method is allowed. Found: GET and GET.
I found solution only for POST and POST.
interface TransportWebService {
#GET(QUERY_CATEGORY_TRANSPORT + "GetTransportByNextStation/{station}")
Observable<ResponseRouteList> getTransportByStation(
#Path("city") String city,
#Path("station") String station,
#Query("count") int count,
#Query("userid") String userId
);
#GET(QUERY_CATEGORY_TRANSPORT + "GetTransportByRoute/{route}")
Observable<ResponseRouteList> getTransportByRoute(
#Path("city") String city,
#Path("station") String route,
#Query("count") int count,
#Query("userid") String userId
);
#GET(QUERY_CATEGORY_TRANSPORT + "Time")
Observable<Integer> getTime(
#Path("city") String city
);
}
UPD: Retrofit version 1.9.0
Init service like this
private static final TransportWebService SERVICE = Common.getRestAdapter()
.setConverter(new GsonConverter(new Gson())
.build()
.create(TransportWebService.class);
In the second GET method, the second argument (#PATH("station")) should be #PATH("route").
I had the same error found: POST and POST, my issue was that I was missing a path parameter in my URL but I was sending it along with the request.
I was hitting the URL without last parameter.
http:www.webtest.requestService/customerapp/{context}/{token}/services/{flightLegId}/
Actual URL was should be:
http:www.webtest.requestService/customerapp/{context}/{token}/services/{flightLegId}/{flightLegExtId}/
This may happen because of tiny mistake like if you are giving parameter like instead of {id}.
The error the "GET and GET" or "POST and POST" error is masking the root exception. It seems the most common exception is that your argument in the HTTP argument method does not match the argument in your Path parameter.
The {id} in #GET("/objects/{id}") must match id in #Path("id").

Categories

Resources