2

Hi i am trying to overide the baseUrl from one specific api call and it doesnt seem to work when using @Url as a paraemter to the api method.

Below is my Api class method

@POST
    fun getUserDetails(@Body body: request, @Url authUrl : String): Single<Response<ResponseData>>

code that cals and make the request

 private fun getApi(): Api {
        val gson = GsonBuilder().setLenient().create()
        val httpClient = myNetworkHelper.createHttpClient()
        val retrofit = Retrofit.Builder()
                .baseUrl("http://defaultBaseUrl")
                .client(httpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()

        return retrofit.create(Api::class.java)
    }

 override fun getUserDetails(someRequestData, "http://dynamic/getuserDetails): Single<Response<ResponseData>> {
        return getApi().getUserDetails(body, url)
    }

The above results in making a request to this url

http://defaultBaseUrl/http://dynamic/getuserDetails

Instead of:

http://dynamic/getuserDetails
Jono
  • 17,341
  • 48
  • 135
  • 217

2 Answers2

3

This is the document from Retrofit @GET annotation:

@Documented 
@Target(METHOD) 
@Retention(RUNTIME) 
public @interface GET {   
/**
* 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 {@link Url @Url}.
* <p>    
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how    
* this is resolved against a base URL to create the full endpoint URL.
*/   
    String value() default ""; 
}

So @Url should be placed as the first parameter, so I think this will work:

@POST
fun getUserDetails(@Url authUrl: String, @Body body: request): Single<Response<ResponseData>>
Boken
  • 4,825
  • 10
  • 32
  • 42
Tam Huynh
  • 2,026
  • 1
  • 16
  • 20
3

I did a test in local and actually I've been able to override the base URL set in the Retrofit instance.

Here's the API:

public interface Api {

    @POST
    Call<Void> fakeService(@Url String url);
}

And here's the "client":

public class Main {

    public static void main(String[] args) throws IOException {
        // Use the HttpLogginInterceptor to check what's the real call
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

        OkHttpClient client = new OkHttpClient.Builder()
                .addNetworkInterceptor(interceptor)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.foo.com/")
                .client(client)
                .build();

        Api api = retrofit.create(Api.class);
        Call<Void> call = api.fakeService("http://www.example.com");
        call.execute();
    }
}

The result is:

Jul 18, 2018 12:28:54 PM okhttp3.internal.platform.Platform log
INFO: --> POST http://www.example.com/ (0-byte body)
Jul 18, 2018 12:28:55 PM okhttp3.internal.platform.Platform log
INFO: <-- 200 OK http://www.example.com/ (366ms, unknown-length body)
user2340612
  • 10,053
  • 4
  • 41
  • 66