/ Java

Clean invocations of dirty methods

I recently started to implement a client for a REST API. I was using RetroFit and here is one the resources used by the client.

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(//
   @Query("projectkey") String projectKey,//
   @Query("repositoryslug") String repositoryslug,//
   @Query("direction") String direction,//
   @Query("at") Integer at,//
   @Query("state") String state,//
   @Query("order") String order,//
   @Query("withattributes") boolean withattributes,//
   @Query("withproperties") boolean withproperties);
}

The problem here is that calls to this service will be dirty. Alot of parameters in each invocation. Alot of strings that can accidentally be added in the wrong order. So just for comparison, here is an invocation of that service.

bitBucketServerService //
 .pullRequests("projectKey", "repositoryslug", "direction", 1, "state", "order", true, true);

I created Java Method Invocation Builder. It adds the @GenerateMethodInvocationBuilder and also @Default. They are added to an interface, or class. It enables default values of method parameters in Java and is making the invocations readable.

@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(//
   @Query("projectkey") String projectKey,//
   @Query("repositoryslug") String repositoryslug,//
   @Default("INCOMING") @Query("direction") String direction,//
   @Query("at") Integer at,//
   @Default("OPEN") @Query("state") String state,//
   @Default("NEWEST") @Query("order") String order,//
   @Default("true") @Query("withattributes") boolean withattributes,//
   @Default("true") @Query("withproperties") boolean withproperties);
}

Java Method Invocation Builder will generate builders for invoking every method in the interface, or class. So that the invoking code can look like this instead.

  BitBucketServerServicePullRequestsBuilder.pullRequests()//
    .withProjectKey("projectKey")//
    .withRepositoryslug("repositoryslug")//
    .withAt(123)//
    .invoke(bitBucketServerService);

The code is generated as Java files at compile time. I created Maven and Gradle examples to show how to use it.

Example