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
Related
I use Retrofit for most of my calls but in one of the cases, I have the full path provided in arguments. My URL is like this http://www.example.com/android.json. This URL is provided in full so I have to path it at runtime. I implement endpoint as suggested here
https://medium.com/#kevintcoughlin/dynamic-endpoints-with-retrofit-a1f4229f4a8d
but in the #GET I need to be able to put #GET(""). This does not work as I get an error saying I should provide at least one "/".
If I add the slash the URL becomes http://www.example.com/android.json/ and it does not work, the server returns forbidden. I also tried creating a custom GET interface similar to here https://github.com/square/retrofit/issues/458 but with GET and without providing a value method in the interface. Then I get another error saying value is missing.
Basically I need to be able to provide an empty or null value but retrofit does not allow that. How could I solve this problem? For now I am doing the JSON request manually but is there a way I could use retrofit for this case? I need to pass the full URL there is no way I can do endpoint http://www.example.com and #GET("/android.json").
Thanks
You can use #GET(".") to indicate that your url is the same as the base url.
#GET(".")
Observable<Result> getData(#Query("param") String parameter);
I've tried this approach, however didn't work for me.
Workaround for this issue is:
//Retrofit interface
public interface TestResourceClient {
#GET
Observable<Something> getSomething(#Url String anEmptyString);
}
//client call
Retrofit.Builder().baseUrl("absolute URL").build()
.create(TestResourceClient.class).getSomething("");
The downside of this solution is that you have to supply empty string in getSomething("") method call.
I face the same problem with Retrofit 2. Using #GET, #GET("") and #GET(".") not solved my problem.
According to the official document you can the same baseUrl and #GET argument.
Endpoint values may be a full URL.
Values that have a host replace the host of baseUrl and values also with a scheme replace the scheme of baseUrl.
Base URL: http://example.com/
Endpoint: https://github.com/square/retrofit/
Result: https://github.com/square/retrofit/
So in my case:
interface MyAPI {
#GET("http://www.omdbapi.com/")
suspend fun getMovies(
#Query("apikey") apikey: String,
#Query("s") s: String
): Response<MoviesResponse>
companion object {
operator fun invoke(): MyAPI {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://www.omdbapi.com/")
.build()
.create(MyAPI::class.java)
}
}
}
I know that we can inject retrofit using dagger in the following manner when the BASE_URL is fixed:
#Provides
#Singleton
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson)).build();
return retrofit;
}
#Provides
#Singleton
ApiCallInterface provideApiCallInterface(Retrofit retrofit) {
return retrofit.create(ApiCallInterface.class);
}
But, the problem here is my BASE_URL comes from firebase remote config, and I can obtain that only after runtime which is too late as dagger will initialize retrofit before that. How can this problem be solved? All the tutorials and examples that I see, work with static base urls and hence dont encounter this problem.
I am using remoteconfig for my base url so that I can control the app environment without pushing in app updates.
Thanks in advance.
According to Retrofit docs
About base_URL:
Endpoint values may be a full URL.
Values which have a host replace the host of baseUrl and values also
with a scheme replace the scheme of baseUrl.
Examples:
Base URL: http://example.com/
Endpoint: https://github.com/square/retrofit/
Result: https://github.com/square/retrofit/
So if endpoint's URL holds full URL, base URL will be replaced|ignored
About GET-annotation (the same with POST):
A relative or absolute path, or full URL of the endpoint. This value
is optional if the first parameter of the method is annotated with
#Url.
So with #URL parameter of your endpoint and empty GET parameter you can set full URL in runtime with parameter #URL of your endpoint
So try with something like this in your endpoint:
#GET()
fun getData(#Url url : String): Call<SomeResult>
and set parameter of method (full URL) in runtime
I found a workaround by leaving the Firebase Remote Config version to 17.0.0 and using the FirebaseRemoteConfig#setDefaults function.
build.gradle
implementation 'com.google.firebase:firebase-config:17.0.0'
Class. Note the setConfigSettingsAsync is still async, setDefaults stays sync.
private final FirebaseRemoteConfig mFirebaseRemoteConfig;
mFirebaseRemoteConfig.setConfigSettingsAsync(new FirebaseRemoteConfigSettings.Builder...);
mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
mFirebaseRemoteConfig.fetchAndActivate().addOnCompleteListener(...)
In addition to the answer above by sergiy tikhonov you can also use an interceptor to intercept your requests and swap the host with your firebase remote config's BASE_URL.
See this gist for an example.
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 use Retrofit for most of my calls but in one of the cases, I have the full path provided in arguments. My URL is like this http://www.example.com/android.json. This URL is provided in full so I have to path it at runtime. I implement endpoint as suggested here
https://medium.com/#kevintcoughlin/dynamic-endpoints-with-retrofit-a1f4229f4a8d
but in the #GET I need to be able to put #GET(""). This does not work as I get an error saying I should provide at least one "/".
If I add the slash the URL becomes http://www.example.com/android.json/ and it does not work, the server returns forbidden. I also tried creating a custom GET interface similar to here https://github.com/square/retrofit/issues/458 but with GET and without providing a value method in the interface. Then I get another error saying value is missing.
Basically I need to be able to provide an empty or null value but retrofit does not allow that. How could I solve this problem? For now I am doing the JSON request manually but is there a way I could use retrofit for this case? I need to pass the full URL there is no way I can do endpoint http://www.example.com and #GET("/android.json").
Thanks
You can use #GET(".") to indicate that your url is the same as the base url.
#GET(".")
Observable<Result> getData(#Query("param") String parameter);
I've tried this approach, however didn't work for me.
Workaround for this issue is:
//Retrofit interface
public interface TestResourceClient {
#GET
Observable<Something> getSomething(#Url String anEmptyString);
}
//client call
Retrofit.Builder().baseUrl("absolute URL").build()
.create(TestResourceClient.class).getSomething("");
The downside of this solution is that you have to supply empty string in getSomething("") method call.
I face the same problem with Retrofit 2. Using #GET, #GET("") and #GET(".") not solved my problem.
According to the official document you can the same baseUrl and #GET argument.
Endpoint values may be a full URL.
Values that have a host replace the host of baseUrl and values also with a scheme replace the scheme of baseUrl.
Base URL: http://example.com/
Endpoint: https://github.com/square/retrofit/
Result: https://github.com/square/retrofit/
So in my case:
interface MyAPI {
#GET("http://www.omdbapi.com/")
suspend fun getMovies(
#Query("apikey") apikey: String,
#Query("s") s: String
): Response<MoviesResponse>
companion object {
operator fun invoke(): MyAPI {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://www.omdbapi.com/")
.build()
.create(MyAPI::class.java)
}
}
}
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.