簡體   English   中英

無法以反應方式在 webflux 中返回請求

[英]Unable to return a request within webflux in reactive manner

這是我的代碼中的以下流程:用戶調用創建代理端點,包含代理名稱和布爾字段 ->

路由器函數接收調用,傳遞給處理程序 ->

處理程序將請求主體轉換為 Mono,將該單聲道傳遞給服務 ->

Service 將代理保存到 DB,在這個過程中生成一個 ID,然后創建一個包含 ID 的 Response 對象包裹在 Mono 中,將 Response 返回給 Handler。

這是我被卡住的部分。 保持反應式方法,我必須將 Agency 保存到 Db 並在 Mono 的“doOnNext() 部分中創建 ID。但是,我無法返回從 DB 獲得的 ID 以創建響應對象。

實現此目的的反應式方法是什么? 提前致謝!

public RouterFunction<ServerResponse> createAgency() {
        return RouterFunctions
                .route(POST("/agency").and(accept(MediaType.APPLICATION_JSON)), handler::createAgency);
    }
@Component
@AllArgsConstructor
public class AgencyHandler {

    private final AgencyServiceImpl service;

    @NonNull
    public Mono<ServerResponse> createAgency(ServerRequest request){
        Mono<CreateAgencyRequest> agency = request.bodyToMono(CreateAgencyRequest.class);

        Mono<CreateAgencyResponse> response = service.createAgency(agency);

        return ServerResponse.created(URI.create("/agency"))
                .contentType(MediaType.APPLICATION_JSON)
                .body(response, CreateAgencyResponse.class);
    }
}
@Service
@AllArgsConstructor
public class AgencyServiceImpl implements AgencyService {
    private final AgencyRepository agencyRepository;
    private final UuidGenerator uuidGenerator;

    public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
        UUID id;
        request.doOnNext(agency -> {
            UUID agencyId = uuidGenerator.getUUID();
            Mono<Agency> newAgency = Mono.just(
                new Agency(
                    agencyId,
                    agency.getFields().getName()
            ));

            //repository.save(newAgency)

            //return Mono.just(new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString())));
        });

        // return request
        return Mono.just(new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString())));
    }
}

doOnNext是副作用,你要找的是flatMap

return request.flatMap(agency -> {
    final UUID agencyId = uuidGenerator.getUUID();
    return repository.save(new Agency(agencyId, agency.getFields().getName()))
        .thenReturn(agencyId);
}).flatMap(id -> ServerResponse.ok()
    .bodyValue(new CreateAgencyResponseData(agencyId.toString()))
    .build();

Wrote this without a compiler to check the code but yu should get the gist of it.

doOnNext不是執行 I/O 綁定操作(例如數據庫訪問)的好選擇。 您應該改用flatmap 另外,請查看用於同步 1 對 1 轉換的map運算符。

最終代碼應如下所示:

  public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
    return request.map(req -> new Agency(uuidGenerator.getUUID(), req.getFields().getName()))
        .flatMap(agency -> repository.save(agency))
        .map(agency -> new CreateAgencyResponse(new CreateAgencyResponseData(agency.getAgencyId())));
  }

像下面這樣的東西應該可以解決問題:

@Service
@AllArgsConstructor
public class AgencyServiceImpl implements AgencyService {
    private final AgencyRepository agencyRepository;
    private final UuidGenerator uuidGenerator;

    public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
        UUID agencyId = uuidGenerator.getUUID();

        return request.flatMap(createAgencyRequest -> {
            Agency agency = new Agency(agencyId, agency.getFields().getName();
            return repository.save(newAgency);    
        }).map(saved ->
            new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString()));
        )
    }
}

您將在flatMap操作中創建Agency並將其存儲在數據庫中。 我假設您的repository也是響應式的,因此它也應該返回Mono ,因此是flatMap操作。 之后,您只需要映射repository返回的任何內容(您可能希望根據對數據庫的成功操作在此處設置一些邏輯)以創建CreateAgencyResponse

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM