How to add Endpoints dynamically in Retrofit2.0 - android

How to pass endpoints in annotations(ex:#GET("dynamic value"))dynamically.
We tried passing values as static and it was doing good but when i pass the values dynamically it is showing the below error
Attribute value must be constant.

It seems that you want to do somthing like this:
#GET("users/list?country={country}")
Call<List<Repo>> listRepos(#Path("country") String country);
where you give the country code when you call the function

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);

Try this :
#Documented
#Target(METHOD)
#Retention(RUNTIME)
public #interface GET {
//new
int Endpoints () default 1; (or use enum)
String value() default "";
}

Related

how to send data to therequest body to the server using retrofit

String Params_body = "{"mobileNumber":"9968599840"}";
String Params_head = "{"clientId":"C11","version":"v1","txnToken":"" + txnToken + ""}";
You have to define your service using the #Header and #Query annotations to indicate the params.
This is just an example of how your service should look like:
public interface RetrofitService {
#GET("/v1/your/endpoint")
Call<YourResponse> networkCall(
#Header("clientId") String clientId,
#Header("version") String version,
#Header("txnToken") String txnToken,
#Query("mobileNumber") String mobileNumber);
}
Then you just need to call the endpoint method and pass as parameter the values.
You can use #Body annotation and pass all the parameter as below class.
class ClienInfo
{
String clientId,
String version,
String txnToken,
String mobileNumber);
}
Use like this:-
#GET("/v1/your/endpoint")
Call<YourResponse> networkCall(#Body ClienInfo clientInfo);

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

Add an array as request parameter with Retrofit 2

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.

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)

Using yahoo weather Api

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;

Categories

Resources