retrofit icon indicating copy to clipboard operation
retrofit copied to clipboard

Allow specifying default @Field values.

Open Folyd opened this issue 10 years ago • 11 comments

As we know,we can use @Field annotation to specify a field in a @POST method, like this:

    @POST
    void doSomething(@Field String params,@Field String anotherParams)

I need specify a default value to a field in a POST request,but i have no idea how to do it.

Does Retrofit support specify a default field for POST request? If not,cloud you add a feature to support this?

    @POST
    @DefaultField(params = "defaultValue")
    void doSomething(@Field String anotherParams)

Any comment is welcome.Thanks.:)

Folyd avatar Jul 09 '15 06:07 Folyd

I am missing this as well. AWS for example uses thousands of default fields which need to be injected on every request. I admit retrofit is not a good choice for a non-REST conform api as AWS [which is not retrofit's fault], but I want to use the same library for all API endpoints in my project, and retrofit is a great choice for all others. I am currently using a custom client implementation where I add these things to the request before it is sent, but it's sort of a mess.

My suggestion would be to add a parameter to either use @DefaultField as mentioned here http://stackoverflow.com/questions/26697054/retrofit-how-to-send-a-post-request-with-constant-fields - but I would also like to see @DefaultFieldMap() where I can add a whole bunch of default fields to a request.

oliverhausler avatar Jul 28 '15 23:07 oliverhausler

+1 for this

IliaEremin avatar Jul 29 '15 11:07 IliaEremin

+1

svenjacobs avatar Aug 13 '15 11:08 svenjacobs

+1!

eginez avatar Dec 12 '15 21:12 eginez

Yet another clamoring for this feature :D

mix3d avatar Feb 03 '16 14:02 mix3d

You may use Java Method Invocation Builder for this.

Then you can annotate the interface like this:

@GenerateMethodInvocationBuilder
public interface BitBucketServerService {
 @GET("/rest/api/1.0/projects/{projectkey}/repos/{repositoryslug}/pull-requests?direction={direction}&at={at}&state={state}&order={order}&withattributes={withattributes}&withproperties={withproperties}")
 Call<BitbucketServerResponse<BitBucketServerPullRequest>> pullRequests(//
   @Default("PROJ") @Query("projectkey") String projectKey,//
   @Default("REPO") @Query("repositoryslug") String repositoryslug,//
   @Default("INCOMING") @Query("direction") String direction,//
   @Default("23") @Query("at") String at,//
   @Default("OPEN") @Query("state") String state,//
   @Default("NEWEST") @Query("order") String order,//
   @Default("true") @Query("withattributes") String withattributes,//
   @Default("true") @Query("withproperties") String withproperties);
}

And only use default values except for the values that you actually want to change, like this:

BitBucketServerServicePullRequestsBuilder.pullRequests()
 .withAt("24")
 .invoke(bitBucketServerService);

tomasbjerre avatar Jun 11 '16 18:06 tomasbjerre

+1,any good ideas ?

Aeiric avatar Jun 29 '16 05:06 Aeiric

@oliverhausler are you sure the solution mentioned at stackoverflow worked?Can you paste your code?

Aeiric avatar Jun 29 '16 06:06 Aeiric

This seems to still be an issue/desire so I thought I'd contribute my two cents of how I've been going about it. You can see my full explanation here but the short version is I define my full @POST method (with all arguments included) in an interface (say, "AuthWebservice"), but then add a second method in the same interface, without any annotations and with only the arguments that I want. I then make a class called AuthWebserviceWrapper that takes an "base" instance of AuthWebservice in its constructor. Most of the time AuthWebserviceWrapper just calls the corresponding methods on the base, but the wrapper class allows you to override the "extra" methods you added to call the base methods with default values. Anywhere you'd retrieve an instance of AuthWebservice (including but not limited to Dagger/DI), you just return an instance of your wrapper, wrapped around the default implementation provided by Retrofit.

slaterama avatar Oct 17 '18 15:10 slaterama

I gave it a raw go at https://github.com/vitorhugods/retrofit/commit/ba191e12388aef9af86775260ecee2ef93458347. The base idea allows static defined parameters, not only @Field, even though I have just implemented the DefaultField so far, but it can be easily replicated.

You can see an example of implementation at the RequestFactoryTest#simpleDefaultFormEncoded:

  @Test public void simpleDefaultFormEncoded() {
    class Example {
      @FormUrlEncoded //
      @POST("/foo") //
      @DefaultParameters(fields = {
        @DefaultField(name = "foo", value = "bar"),
        @DefaultField(name = "ping", value = "pong")
      })
      Call<ResponseBody> method(@Field(value = "John") String person) {
        return null;
      }
    }
    Request request = buildRequest(Example.class, "Doe");
    RequestBody body = request.body();
    assertBody(body, "John=Doe&foo=bar&ping=pong");
    assertThat(body.contentType().toString()).isEqualTo("application/x-www-form-urlencoded");
  }

I would really appreciate some feedback.

vitorhugods avatar Jan 24 '19 12:01 vitorhugods