Why does Retrofit add forward slashes to all urls?

Editing a question with detailed information:

I understand the use of service interfaces in Retrofit. I want to call a url like this: http://a.com/b/c (and then add request parameters using the service interface).

My limitations:

  • I cannot use / b / c as part of the service interface (as a path parameter). I need this as part of the base url. I have explained the reason in detail below.

  • I cannot afford to get the resulting call at http://a.com/b/c/?key=val . I need http://a.com/b/c?key=val (trailing slash after "c" creates problems for my API). See below for details.

My server API changes quite often and I am facing client side issues with Retrofit. The main problem is that we cannot have dynamic values ​​(not final) passed in @GET or @POST annotations for path parameters (for example, this is possible for request parameters). For example, even the number of path parameters changes when the API changes. We cannot afford to have different interfaces every time the API changes.

A workaround for this is to generate all urls, i.e. the endpoint with Base_Url + Path_Parameters.

But I'm wondering why Retrofit forcibly adds a trailing slash ("/") to the base url:

        String API_URL = "https://api.github.com/repos/square/retrofit/contributors";
        if (API_URL.endsWith("/")) {
            API_URL = API_URL.substring(0, API_URL.length() - 1);
        }
        System.out.println(API_URL);   //prints without trailing "/"

        RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(API_URL)
        .build();

      

API_URL is always reset to https://api.github.com/repos/square/retrofit/contributors/ using Retrofit internally (confirmed this by logging request)

The workaround for this is manual addition? at the end to prevent adding "/": https://api.github.com/repos/square/retrofit/contributors ?

Unfortunately, this request will not be accepted by our API.

  • Why does Retrofit force this behavior?
  • Is there a solution for people like me who don't want to be left behind?
  • Can we have variable parameters (not final) that are passed in the Retrofit @GET or @POST annotations?
+3


source to share


1 answer


You are expected to pass the base url to setEndpoint(...)

and define /repos/...

in your service interface.

Quick demo:

class Contributor {

    String login;

    @Override
    public String toString() {
        return String.format("{login='%s'}", this.login);
    }
}

interface GitHubService {

    @GET("/repos/{organization}/{repository}/contributors")
    List<Contributor> getContributors(@Path("organization") String organization,
                                      @Path("repository") String repository);
}

      

and then in your code:

GitHubService service = new RestAdapter.Builder()
        .setEndpoint("https://api.github.com")
        .build()
        .create(GitHubService.class);

List<Contributor> contributors = service.getContributors("square", "retrofit");
System.out.println(contributors);

      

which will print:



[{login = 'JakeWharton'}, {login = 'pforhan'}, {login = 'edenman'}, {login = 'eburke'}, {login = 'swankjesse'}, {login = 'dnkoutso'}, { login = 'loganj'}, {login = 'rcdickerson'}, {login = 'rjrjr'}, {login = 'kryali'}, {login = 'holmes'}, {login = 'adriancole'}, {login = 'swanson'}, {login = 'crazybob'}, {login = 'danrice-square'}, {login = 'Turbo87'}, {login = 'ransombriggs'}, {login = 'jjNford'}, {login = 'icastell'}, {login = 'codebutler'}, {login = 'koalahamlet'}, {login = 'austynmahoney'}, {login = 'mironov-nsk'}, {login = 'kaiwaldron'}, {login = 'matthewmichihara'}, {login = 'nbauernfeind'}, {login = 'hongrich'}, {login = 'thuss'}, {login =' xian '}, {login ='jacobtabak '}]

Can we have variable parameters (not final) that are passed in the Retrofit @GET or @POST annotations?

No, the values ​​inside the (Java) annotation must be declared final. However, you can define path variables as shown in the demo.

EDIT:

Note Jake remarks in the comments:

It should be noted that the code linked in the original question is about the case where you pass https://api.github.com/ (note the trailing slash) and that is appended to / repos / ... (note the leading slash). Overrides forces leading to forward slashes on relative parameters of URL annotation, so it will de-duplicate if there is a trailing slash in the API URL.

+1


source







All Articles