URL query syntax for Android Retrofit - android

I'm trying to use Retrofit to get data from the Overpass API for OpenStreetMap.
The URL String for a GET request looks like this:
http://www.overpass-api.de/api/xapi?way[highway=track][bbox=-122.53,37.86,-122.52,37.87]
As far as I can tell, the RestAdapter would look something like this:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.overpass-api.de")
.build();
and GET method in the interface would look something like this:
#GET("/api/xapi")
Response listWays(WHAT GOES HERE??);
The existence of "way" without an accompanying =someValue and the [highway=track] and [bbox=...] in brackets both seem a bit out of the ordinary.
How should I write this interface method for this GET request?

I think in this situation you should use #Query parameter of retrofit.

Related

How to call dotnet api from Retrofit?

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.

Android Retrofit - how to override baseUrl

In the retrofit adapter i have used a base Url for all my calls. so:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.build();
GitHubService service = retrofit.create(GitHubService.class);
Lets say the above is my code, all my calls now use that baseUrl. But for one particular call, i want to change the base url, I dont want to create another rest adapter for this,as its just for testing locally. Can i change the end points in the interface possibly to not use the baseurl , or is there a annotation to supply my own base url ?
you can use the #Url annotation to provide the full complete url. E.G.
#GET
Call<GitHubUser> getUser(#Url String url);
In retrofi2 the path in #GET overrides the base URL.
#GET("https://someurl/api/supermarkets")
Observable<List<TechIndex>> getTechIndexList();
The request will be send to "someurl/api/.." no matter what base url is.
Hope it helps

Retrofit use only setEndpoint() and in the #PUT leave empty in android

i am trying to use the RestAdapter with setEndpoint(BASE_URL), and in the interface leave the #PUT(null), is it possible?
the reason why is because i am getting the URL as an answer from the server and i just need this URL to call PUT.
Thanks
I have not tested this, but if I were you I would try to write it like the endpoint you want to call, is dynamically added with the retrofit URL manipulation "#Path("")".
#PUT("{endPoint}")
void somethingSomething(#Path("endpoint") String endPoint, Callback<T> cb)
And then have the base url set in the retrofit restadapter when you initialize it.

Retrofit: add runtime parameter to interface?

I would like to always add a parameter to my Retrofit calls. For values that I can hard code I can simply use
#POST("/myApi?myParam=myValue")
but what if I want to append android.os.Build.MODEL?
#POST("/myApi?machineName="+ Build.MODEL)
doesn't work. It would be useful to be able to abstract this part of the network call away from the implementing code.
EDIT
I can add Build.MODEL to all of my api calls by using a RequestInterceptor. However it still eludes me how to add it selectively to only some of my api calls while still using the same RestAdapter.
EDIT 2
Fixed the title which was all sorts of wrong.
EDIT 3
Current implementation:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("myapi")
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestInterceptor.RequestFacade request) {
request.addQueryParam("machineName", Build.MODEL);
}
})
.build();
API_SERVICE = restAdapter.create(ApiService.class);
Build.MODEL is not available for use in an annotation because it cannot be resolved at compile time. It's only available at runtime (because it loads from a property).
There are two ways to accomplish this. The first is using a RequestInterceptor which you mention in the question.
The second is using a #Query parameter on the method.
#POST("/myApi")
Response doSomething(#Query("machineName") String machineName);
This requires you to pass Build.MODEL when invoking the API. If you want, you can wrap the Retrofit interface in an API that's more friendly to the application layer that does this for you.

Retrofit/Robospice: get response headers from successful request?

I am using Retrofit/Robospice to make api calls in an app I've built, with a RetrofitGsonSpiceService. All responses are converted into POJOs using a GSON converter, however there is some information I need to retrieve from the response header. I cannot find any means to get the headers (I can only get the headers if the request is unsuccessful because the raw response is sent in the error object!) how can I intercept the response to grab the headers before it is converted?
It took me a few minutes to figure out exactly what #mato was suggesting in his answer. Here's a concrete example of how to replace the OkClient that comes with Retrofit in order to intercept the response headers.
public class InterceptingOkClient extends OkClient
{
public InterceptingOkClient()
{
}
public InterceptingOkClient(OkHttpClient client)
{
super(client);
}
#Override
public Response execute(Request request) throws IOException
{
Response response = super.execute(request);
for (Header header : response.getHeaders())
{
// do something with header
}
return response;
}
}
You then pass an instance of your custom client to the RestAdapter.Builder:
RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new InterceptingOkClient())
....
.build();
RoboSpice was designed in a way it doesn't know anything about the HTTP client you end up using in your app. That being said, you should get the response headers from the HTTP client. As Retrofit may use Apache, OkHttp or the default Android HTTP client, you should take a look and see which client you are currently using. Take into account that Retrofit chooses the HTTP client based on certain things (please refer to the Retrofit documentation, or dig into the code, you will find it), unless you manually specify it.
Retrofit defines an interface for clients called Client. If you take a look at the source code, you will see that three classes implement this interface: ApacheClient, OkClient and UrlConnectionClient. Depending on which of them you want to use, extend from one of those, and try to hook into the code that is executed when a response comes back, so that you can get the headers from it.
Once you do that, you have to set your custom Client to Retrofit.

Categories

Resources