Spring WebClient вызывает два зависимых API

У меня две конечные точки, первая - http://localhost:8899/api/composition/appraisal, которая вернет все данные оценки производительности.

[
    {
        "appraisalId": "ac234fbf-740c-4390-89d4-0e9753ad4d70",
        "employeeId": "emp-4613",
        "grade": "VERY_GOOD",
        "score": 94,
        "status": "NEW"
    },
    {
        "appraisalId": "e9baf663-aa6e-4af8-ae16-ef50c886df28",
        "employeeId": "emp-4623",
        "grade": "VERY_GOOD",
        "score": 94,
        "status": "NEW"
    }
]

У меня также есть еще одна конечная точка для получения бонусных данных http://localhost:8888/api/composition/bonus/{appraisal_id}, которые возвращают бонусные данные на основе идентификатора оценки.

{
    "appraisalId": "ac234fbf-740c-4390-89d4-0e9753ad4d70",
    "bonusAmount": 4760.0,
    "bonusPaidDate": "2019-06-30",
    "employeeId": "emp-4623",
    "paidToBankAccount": "8240996587"
}

Передав appraisal_id из первого API в качестве параметра, я должен объединить результат обоих вызовов API в класс PerformanceAppraisalWithBonus.java.

public class PerformanceAppraisalWithBonus {
    private UUID appraisalId;
    private double bonusAmount;
    private LocalDate bonusPaidDate;
    private String employeeId;
    private String grade;
    private int score;
    private String status;

    getters / setters
}

Как я могу добиться этого с помощью Spring WebClient?


person Timothy    schedule 31.01.2020    source источник


Ответы (1)


предполагая, что второй api http://localhost:8888/api/composition/bonus/{appraisal_id} отвечает 204 No content, когда он не находит или не существует идентификатора, и, в свою очередь, предполагая, что ожидаемый ответ представляет собой список PerformanceAppraisalWithBonus (Flux), тогда это будет выглядеть так:

webClient

@Component
public class TestClient {


  public Flux<Appraisal> firstServiceList() {

    return WebClient.create()
            .get()
            .uri("http://demo4307830.mockable.io/first")
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToFlux(Appraisal.class);

  }

  public Mono<AppraisalBonus> firstServiceFindId(UUID uuid) {

    return WebClient.create()
            .get()
            .uri("http://demo4307830.mockable.io/"+ uuid)
            .accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(AppraisalBonus.class);

  }
}

Услуга

@Service
public class AppraisalServiceImpl {

  @Autowired
  private TestClient testClient;

  public Flux<AppraisalCombine> combineTwo() {
    return testClient.firstServiceList()
            .flatMap(appraisal -> testClient.firstServiceFindId(appraisal.getAppraisalId())
                    .flatMap(appraisalBonus -> Mono.just(AppraisalCombine.builder()
                            .appraisalId(appraisalBonus.getAppraisalId())
                            .bonusAmount(appraisalBonus.getBonusAmount())
                            .bonusPaidDate(appraisalBonus.getBonusPaidDate())
                            .employeeId(appraisalBonus.getEmployeeId())
                            .grade(appraisal.getGrade())
                            .score(appraisal.getScore())
                            .status(appraisal.getStatus())
                            .build())));

  }
}

Контроллер

@RestController
@RequestMapping("/appraisal")
public class AppraisalController {

  @Autowired
  AppraisalServiceImpl appraisalService;

  @GetMapping(value = "/get")
  public Flux<AppraisalCombine> uploadSimple() {
    return appraisalService.combineTwo();
  }
}

результат

[
    {
        "appraisalId": "ac234fbf-740c-4390-89d4-0e9753ad4d70",
        "bonusAmount": 4760.0,
        "bonusPaidDate": "2019-06-30",
        "employeeId": "emp-4623",
        "grade": "VERY_GOOD",
        "score": 94,
        "status": "NEW"
    }
]
person Raúl Ortiz    schedule 31.01.2020