Spring WebClient调用两个依赖API

Spring WebClient Call Two Dependent API

我有两个端点,第一个是http://localhost:8899/api/composition/appraisal,它将return所有绩效评估数据

[
    {
        "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} 其中 return 奖金数据基于评估 ID

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

将第一个 API 的 appraisal_id 作为参数,我必须将两个 API 调用的结果合并到 PerformanceAppraisalWithBonus.java class

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 实现此目的?

假设第二个 api http://localhost:8888/api/composition/bonus/{appraisal_id} 回复 204 No content 当它没有找到或不存在 id 并且反过来假设预期的响应是 PerformanceAppraisalWithBonus (Flux) 的列表 那么它看起来像这样:

网络客户端

@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"
    }
]