我不知道如何使用webflux创建适当的流程

时间:2018-10-21 07:31:20

标签: spring-webflux

问题陈述:我对预订服务 API发出POST请求,该请求获得了BookingRecord。我将其映射以提取值,以便使用WebClient调用另一个票价服务 API。我从该呼叫中收到了Mono<Fare>。我需要检查BookingRecord类型的getFare()方法的值是否与WebClient返回的Fare类型的getFare()相同。如果没有,我需要引发和异常,并将其传递给调用方。这里的调用者是另一个微服务, ui-service ,它调用预订服务API(因此,我该如何处理,将错误传回,否则最好的办法是什么?)否则我会保存新的BookingRecord并将该记录的ID返回给调用方。最佳的流程顺序是什么?我尽了最大努力,但并没有成功,并且将代码粘贴到此处。

public HandlerFunction<ServerResponse> book = request ->
    {
request.bodyToMono(BookingRecord.class)
        .map(br ->
        {
            this.webClient.get()
                    .uri("/fares/get/{flightNumber}/{flightDate}",
                         br.getFlightNumber(),
                         br.getFlightDate())
                    .retrieve()
                    .bodyToMono(Fare.class)
                    .map(f ->
                    {
                        if (!f.getFare()
                                .equals(br.getFare()))
                        {
                            throw new RuntimeException("Fare is tampered");
                        }
                        else
                        {
                            id = bookingRepository.save(br).getId();
                        }
                        return id;
                    })
                    .subscribe();
            return id;
        });

return ServerResponse.ok()
        .body(BodyInserters.fromObject(id));
};

1 个答案:

答案 0 :(得分:0)

经过大量调整后,这就是我所做的。希望它做对了。 1.我从票价服务本身而不是在预订服务中提出了500 Http错误。

public HandlerFunction<ServerResponse> getFare = request ->
    {
        String flightNumber = request.pathVariable("flightNumber");
        String flightDate   = request.pathVariable("flightDate");
        String fare         = request.pathVariable("fare");

        Mono<ServerResponse> notFound = ServerResponse.notFound()
                .build();

        return Mono
                .justOrEmpty(faresRepository.getFareByFlightNumberAndFlightDateAndFare(flightNumber,
                                                                                       flightDate,
                                                                                       fare))
                .flatMap(f -> ServerResponse.ok()
                        .contentType(APPLICATION_JSON)
                        .body(fromObject(f)))
                .switchIfEmpty(notFound);
    };
  1. 使用onStatus()方法处理预订服务中的异常

    public HandlerFunction<ServerResponse> book = request ->
    {
    
        logger.info("Inside Book function");
        return request.bodyToMono(BookingRecord.class)
                .flatMap(br ->
                {
                    logger.info("Calling fare-service");
                    return this.webClient.get()
                            .uri("/fares/get/{flightNumber}/{flightDate}/{fare}",
                                 br.getFlightNumber(),
                                 br.getFlightDate(),
                                 br.getFare())
                            .retrieve()
                            .onStatus(HttpStatus::isError,
                                      x -> Mono
                                              .error(new RuntimeException("Fare has been tampered with!!")))
                            .bodyToMono(Fare.class);
    
                })
                .map(fare ->
                {
                    logger.info("Saving a BookingRecord");
                    BookingRecord br = new BookingRecord();
                    br.setFlightNumber(fare.getFlightNumber());
                    br.setFlightDate(fare.getFlightDate());
                    br.setFare(fare.getFare());
    
                    long id = bookingRepository.save(br)
                            .getId();
    
                    return id;
                })
                .flatMap(id -> ServerResponse.ok()
                        .body(BodyInserters.fromObject(id)));
    };
    

这样,我就获得了票价篡改的例外,或者获得了成功保存数据库的ID。