I wanted to use retrofit library for parsing and posting the data by passing some parameters. But When defining model class some times we will use #Serialized in-front of variable, What is the use of that Serialized.And What is the difference between #Get and #Query in passing params to API.Can Any one explain the difference.
Lets say you have api method #GET("/api/item/{id}/subitem/") so by using #Path("id") you can specify id for item in path. However your api may take additional parameters in query like sort, lastupdatetime, limit etc so you add those at end of url by #Query(value = "sort") String sortQuery
So full method will look like:
#GET("/api/item/{id}/subitem")
SubItem getSubItem(#Path("id") int itemId, #Query("sort") String sortQuery, #Query("limit") int itemsLimit);
and calling api.getSubItem(5, "name", 10) will produce url #GET("/api/item/5/subitem/?sort=name&limit=10")
and #Get is HTTP method
http://www.w3schools.com/tags/ref_httpmethods.asp says
Two commonly used methods for a request-response between a client and
server are: GET and POST.
GET - Requests data from a specified resource POST - Submits data to
be processed to a specified resource
#GET is request method. You mark method with that.
#Query is query parameter (i.e. the one in the URL). You mark method parameters with that.
#Serialized probably does not belong to Retrofit, look at its package name (move cursor there and press `Ctrl+Q in Android studio)
Related
I am using Retrofit2 and RxJava in my application. I have to pass multiple values corresponding to single key. Below is my request URL
https://api.openweathermap.org/data/2.5/onecall?lat=28.46&lon=77.03&exclude=hourly,alerts,minutely&appid=01s
Now in above URL there is exclude key in which multiple parameters are passing how to add these in my interface. Below is my interface.
ApiService.class
interface ApiService {
#GET("data/2.5/onecall")
fun getCurrenttemp(#Query("lat") lat:String,
#Query("lon") lon:String,
#Query("exclude") exclude:String,
#Query("appid") appid:String):Observable<Climate>
}
How can I make the desired request?
As the exclude parameter portion in the documentation of One Call API says,
By using this parameter you can exclude some parts of the weather data from the API response. It should be a comma-delimited list (without spaces).
So it's not asking for multiple values, it's rather one String value with comma-separated option tags with no spaces between them. Just put "hourly,alerts,minutely" in a String variable & pass that string as you already have in the following line of code, #Query("exclude") exclude:String, via your interface and it should work:
var excludeParamToPass = "hourly,alerts,minutely"
One example of API from that same reference:
https://api.openweathermap.org/data/2.5/onecall?lat=33.441792&lon=-94.037689&exclude=hourly,daily&appid={API key}
i want to get a data on Internet use Retrofit Library
my code look like this :
#GET("?key={key}&q={quotes}")
Call<List<Pixabay.hits>> getTheData(#Query("key") String key, #Query("quotes") String quotes);
java.lang.IllegalArgumentException: URL query string key={key}&q={quotes} must not have replace block. For dynamic query parameters use #Query.
for method api.getTheData
I get that problem, how to solve this? thank you.
you don't have to write query parameters in your path.
#Query will do that for you.
replace
#GET("?key={key}&q={quotes}")
with
#GET("/")
Precisely, {something} parameter can be used only in path variable.
For example,
#GET("/key/{key}")
In this case, you can use #Path annotation instead of #Query.
If you specify #GET("key?a=5"), then any #Query("b") must be appended using &, producing something like key?a=5&b=7.
If you specify #GET("key"), then the first #Query must be appended using ?, producing something like key?b=7.
So in your case no need to implement here like ?key={key}&q={quotes} just add
your domain #GET("your_domain/")
This day is the first time for me to use dotNet web API for my project.
This is the code of my controller
public IEnumerable<Waybill> Get(string id_wb) {
List<Waybill> lstWaybill = new List<Waybill>();
lstWaybill = objway.GetWaybill(id_wb).ToList();
return lstWaybill;
}
That API can work well if I'm call using this link :
http://localhost:56127/api/waybill/?id_wb=00000093
but I don't know how to call that link from my android app (I'm using retrofit)
#GET("Waybill/{id_wb}/id_wb")
Call<Waybill> getWaybillData(#Path("id_wb") String id_wb);
There are 3 options.
First one is to use Retrofit's #Query annotation.
#GET("Waybill/")
Call<Waybill> getWaybillData(#Query("id_wb") String id_wb);
The second one is to #Path annotation
#GET("Waybill/?id_wb={id_wb}") // notice the difference in your code and my code
Call<Waybill> getWaybillData(#Path("id_wb") String id_wb);
The third option is to use #Url annotation. With this option, you need to prepare fully qualified URL before calling/using getWaybillData() method in your activity or fragment. Keep in mind that #Url method overrides base URL set in Retrofit client.
#GET // notice the difference in your code and my code
Call<Waybill> getWaybillData(#Url String completeUrl);
If you follow 3rd option you need to prepare full URL in your activity like below.
String url = "http://<server_ip_address>:56127/api/waybill/?id_wb=00000093";
YourInterface api = ...
Call<Waybill> call = api.getWaybillData(url);
call.enqueue({/* implementation */});
I see a difference in the sample URL you mentioned and usage in Retrofit API interface.
In sample URL waybill is small and in API interface it is Waybill. Please ensure that you're using the right URL.
I am trying to make an API call to a mobile backend with Retrofit 2.0. In my API call, i have to make necessary call to this URL
https://api.backendless.com/v1/data/Users?where=followings.objectId=%270B3BA7F9-260F-B378-FF9A-3C2448B8A700%27
To form this URL in Retrofit i have been using below interface
#GET("Users?where=")
Call<List<User>> getFollowers(#Query("followings.objectId") String objectId);
This interface call puts an ampersand before the query parameters and generates a URL like below
https://api.backendless.com/v1/data/Users?where=&followings.objectId=%270B3BA7F9-260F-B378-FF9A-3C2448B8A700%27
I tried to overcome this with Path annotation but i keep getting "URL query string must not have replace block. For dynamic query parameters using #Query" error.
API that i am trying to connect requires a "where=" clause for filtering by design. I have no permission to change that. What i want is somehow tell Retrofit not to put an ampersand sign before the query parameter or any workarounds for this issue.
Any help is appreciated.
For those who seek for similar answers, I came up with below solution
I declared my interface with #Url
#GET
Call<List<User>> getFollowers(#Url String objectId);
and generated related URL part as an extension method
public String toFollowerRequest(){
return RestGlobals.BASE_URL + "Users?where=followings.objectId=%27" + objectId + "%27";
}
#GET("{path}")
Call> getFollowers(#Path("path") path, #Query("followings.objectId") String objectId);
getFollowers("Users?where=", ...)
Editing question with more details :
I understand the use of service interfaces in Retrofit. I want to make a call to a URL like this :
http://a.com/b/c (and later append query parameters using a service interface).
My limitations are :
I cannot use /b/c as a part of service interface (as path parameter). I need it as a part of base url. I have detailed the reason below.
I cannot afford to have a resultant call being made to http://a.com/b/c/?key=val. What I need is http://a.com/b/c?key=val (the trailing slash after "c" is creating problems for my API). More details below.
My Server API changes pretty frequently, and I am facing trouble on the client side using Retrofit. The main problem is that we cannot have dynamic values (non final) passed to #GET or #POST annotations for Path Parameters (like it is possible for query parameters). For example, even the number of path parameters change when the API changes. We cannot afford to have different interfaces everytime the API changes.
One workaround to this is by forming the complete URLs, that is, an Endpoint with Base_Url + Path_Parameters.
But I am wondering why is Retrofit forcibly adding a trailing slash ("/") to the base url :
String API_URL = "https://api.github.com/repos/square/retrofit/contributors";
if (API_URL.endsWith("/")) {
API_URL = API_URL.substring(0, API_URL.length() - 1);
}
System.out.println(API_URL); //prints without trailing "/"
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.build();
API_URL is always being reset to https://api.github.com/repos/square/retrofit/contributors/ by Retrofit internally (confirmed this by logging the request)
One workaround to this is by manually adding a "?" in the end to prevent "/" to be added: https://api.github.com/repos/square/retrofit/contributors?
Unfortunately, such request won't be accepted by our API.
Why is Retrofit forcing this behavior ?
Is there a solution for people like me who don't want a trailing slash ?
Can we have variable parameters (non final) being passed to Retrofit #GET or #POST annotations ?
You're expected to pass the base URL to the setEndpoint(...) and define /repos/... in your service interface.
A quick demo:
class Contributor {
String login;
#Override
public String toString() {
return String.format("{login='%s'}", this.login);
}
}
interface GitHubService {
#GET("/repos/{organization}/{repository}/contributors")
List<Contributor> getContributors(#Path("organization") String organization,
#Path("repository") String repository);
}
and then in your code, you do:
GitHubService service = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.build()
.create(GitHubService.class);
List<Contributor> contributors = service.getContributors("square", "retrofit");
System.out.println(contributors);
which will print:
[{login='JakeWharton'}, {login='pforhan'}, {login='edenman'}, {login='eburke'}, {login='swankjesse'}, {login='dnkoutso'}, {login='loganj'}, {login='rcdickerson'}, {login='rjrjr'}, {login='kryali'}, {login='holmes'}, {login='adriancole'}, {login='swanson'}, {login='crazybob'}, {login='danrice-square'}, {login='Turbo87'}, {login='ransombriggs'}, {login='jjNford'}, {login='icastell'}, {login='codebutler'}, {login='koalahamlet'}, {login='austynmahoney'}, {login='mironov-nsk'}, {login='kaiwaldron'}, {login='matthewmichihara'}, {login='nbauernfeind'}, {login='hongrich'}, {login='thuss'}, {login='xian'}, {login='jacobtabak'}]
Can we have variable parameters (non final) being passed to Retrofit #GET or #POST annotations ?
No, values inside (Java) annotations must be declared final. However, you can define variable paths, as I showed in the demo.
EDIT:
Note Jake's remark in the comments:
Worth noting, the code linked in the original question deals with the case when you pass https://api.github.com/ (note the trailing slash) and it gets joined to /repos/... (note the leading slash). Retrofit forces leading slashes on the relative URL annotation parameters so it de-dupes if there's a trailing slash on the API url.