Симулировать отображение клиента по параметру

У меня есть симулированный клиент, который выглядит примерно так:

@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmMedium", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmMediumBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);


@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmCampaign", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmCampaignBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);


@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmSource", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmSourceBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);

Как видите, три метода одинаковы для различий в пути API, который изменяется в зависимости от параметра. utmMedium, utmCampaign а также utmSource как на стороне сервера, мы относимся к ним по-разному.

Я не могу изменить сервер, поэтому я не могу изменить конечную точку для принятия этого параметра в качестве параметра запроса или чего-то еще. Интересно, есть ли способ для меня по-прежнему параметризовать эту часть пути, чтобы у меня был только один метод вместо трех?

1 ответ

Вы можете определить дополнительный параметр с @PathVariable аннотация, как показано ниже utmType,

@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/{utmType}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmCampaignBreakdowns(
    @RequestBody Record record,
    @PathVariable("utmType") String utmType,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);

Вы должны быть осторожны в том, что вам нужно указать имя utmType лайк @PathVariable("utmType") с аннотацией.

Если вы хотите добавить к альтернативным URI проверки времени компиляции, для параметра utmType можно использовать String Enum. Предполагается, что вы используете Spring Open Feign. Для Plain Feign потребуются альтернативные аннотации, некоторые начальные инструкции для этого случая можно найти здесь.:

//Slight changes should be introduced in the getUtmCampaignBreakdowns method signature utmType parameter.
package test;

import java.time.ZonedDateTime;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "utmThing", url = "${feign.client.config.utmThing.url}")
public interface Test {
  @PostMapping(value = "/breakdowns/{utmType}", consumes = MediaType.APPLICATION_JSON_VALUE)
  List<Breakdown> getUtmCampaignBreakdowns(
      @RequestBody Record record,
      @PathVariable("utmType") UtmTypes utmType, //<-Type changed to Enum
      @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
      @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
      @RequestParam("timezone") String timezone
  );
}


//An enum should be declared
package test;

enum UtmTypes {
  UTM_MEDIUM("utmMedium"),
  UTM_CAMPAIGN("utmCampaign"),
  UTM_SOURCE("utmSource");

  private final String utmType;

  UtmTypes(String utmType) {
        this.utmType = utmType;
  }

  //Do not forget to privide a toString() that would map to the URI parameter
  public String toString() {
    return utmType;
  }
}

//Can be used like so:
package test;

import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.TimeZone;
import org.springframework.beans.factory.annotation.Autowired;

public class User {

  @Autowired
  void User(Test test) {
    test.getUtmCampaignBreakdowns(new Record(), UtmTypes.UTM_CAMPAIGN, ZonedDateTime.now(),
        ZonedDateTime.now().plusDays(1),
        Arrays.stream(TimeZone.getAvailableIDs())
            .filter(zoneName -> zoneName.contains("Montevideo")).findFirst()
            .orElse(TimeZone.getAvailableIDs()[0]));
  }
}

//Assuming simple Record and Breakdown implementations
package test;

public class Record {
  private String someField;

  public void setSomeField(String someField) {
    this.someField = someField;
  }

  public String getSomeField() {
    return this.someField;
  }
}

package test;

public class Record {
  private String someField;

  Record() {
    this.someField = "defaultValue";
  }

  public void setSomeField(String someField) {
    this.someField = someField;
  }

  public String getSomeField() {
    return this.someField;
  }
}
Другие вопросы по тегам