Retrofit 2 - Dynamic Url

Retrofit 2 - Dynamic URL

I think you are using it in wrong way. Here is an excerpt from the changelog:

New: @Url parameter annotation allows passing a complete URL for an endpoint.

So your interface should be like this:

public interface APIService {
@GET
Call<Users> getUsers(@Url String url);
}

Set dynamic base url using Retrofit 2.0 and Dagger 2

Support for this use-case was removed in Retrofit2. The recommendation is to use an OkHttp interceptor instead.

HostSelectionInterceptor made by swankjesse

import java.io.IOException;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/** An interceptor that allows runtime changes to the URL hostname. */
public final class HostSelectionInterceptor implements Interceptor {
private volatile String host;

public void setHost(String host) {
this.host = host;
}

@Override public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String host = this.host;
if (host != null) {
//HttpUrl newUrl = request.url().newBuilder()
// .host(host)
// .build();
HttpUrl newUrl = HttpUrl.parse(host);
request = request.newBuilder()
.url(newUrl)
.build();
}
return chain.proceed(request);
}

public static void main(String[] args) throws Exception {
HostSelectionInterceptor interceptor = new HostSelectionInterceptor();

OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();

Request request = new Request.Builder()
.url("http://www.coca-cola.com/robots.txt")
.build();

okhttp3.Call call1 = okHttpClient.newCall(request);
okhttp3.Response response1 = call1.execute();
System.out.println("RESPONSE FROM: " + response1.request().url());
System.out.println(response1.body().string());

interceptor.setHost("www.pepsi.com");

okhttp3.Call call2 = okHttpClient.newCall(request);
okhttp3.Response response2 = call2.execute();
System.out.println("RESPONSE FROM: " + response2.request().url());
System.out.println(response2.body().string());
}
}

Or you can either replace your Retrofit instance (and possibly store the instance in a RetrofitHolder in which you can modify the instance itself, and provide the holder through Dagger)...

public class RetrofitHolder {
Retrofit retrofit;

//getter, setter
}

Or re-use your current Retrofit instance and hack the new URL in with reflection, because screw the rules. Retrofit has a baseUrl parameter which is private final, therefore you can access it only with reflection.

Field field = Retrofit.class.getDeclaredField("baseUrl");
field.setAccessible(true);
okhttp3.HttpUrl newHttpUrl = HttpUrl.parse(newUrl);
field.set(retrofit, newHttpUrl);

Dynamic Url with @Post request retrofit + hilt

@Url is a parameter annotation allows passing a complete URL for an endpoint, so it's not a base url, but it's the full endpoint url, and you can't use it with dynamic path @POST("{id}"), this must be like that @POST() and also @Querycan't be used with @Url, so you have two solutions:

  1. The first is by keeping @Url and generate the full url by yourself (generate a url will the query) and give it to getConfiguration(url) function:

code:

@POST()
suspend fun getConfiguration(
@Url url: String,
): Config

  1. The second which is not recommended but it's easier, which is creating a new retrofit instance with the other base url and other api interface provided by the new retrofit instance, and with you can keep using Query:

code:

@POST("{id}")
suspend fun getConfiguration(
@Body configRequest: ConfigRequest,
@Query("id") id: String
): Config

Retrofit 2 - Dynamic URL

I think you are using it in wrong way. Here is an excerpt from the changelog:

New: @Url parameter annotation allows passing a complete URL for an endpoint.

So your interface should be like this:

public interface APIService {
@GET
Call<Users> getUsers(@Url String url);
}

How i change the retrofit URL at runtime

you must have to add these lines in your code:

First Step:
Add the new CallAdapter RxJavaCallAdapterFactory.create() when building a Retrofit instance.

public static final String BASE_URL = "http://google.com/";
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}

Next step:
Update the APIService for example:-> savePost(String title, String body, String userId) method to become an Observable.

public interface APIService {
@GET
Call<ResponseBody> list(@Url String url);
//or

@POST("/posts")
@FormUrlEncoded
Observable<Post> savePost(@Field("title") String title,
@Field("body") String body,
@Field("userId") long userId);
}

Final step:
When making the requests, our anonymous subscriber responds to the observable's stream which emits event.

public void sendPost(String title, String body) {

// RxJava
mAPIService.savePost(title, body, 1).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Post>() {
@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(Post post) {
showResponse(post.toString());
}
});
}

this is way you build your dynamic urls: want to learn more details full description link: Sending Data With Retrofit 2 HTTP Client for Android

and See base URL for details of how the value will be resolved against a base URL to create the full endpoint URL.

if you are doing using kotlin: follow this link. dynamic urls at Runtime with Retrofit 2

Add dynamic value in url retrofit

The exception is self-explanatory, You need to use a query parameter for key. Something like

@GET("storage/presigned-url?bucketName=files&httpVerb=2&contentType=image/jpeg")
suspend fun fileUploadPathCheque(@Query("key") name: String): Response<String>`

and then call it appending payment-receipt/ to your passing parameter:

Api.fileUploadPathCheque("payment-receipt/" + UUID.randomUUID().toString().plus(".jpg"))

This should work for you.



Related Topics



Leave a reply



Submit