Spring WebFlux - how to get data from DB to use in the next step

前端 未结 1 459
野性不改
野性不改 2021-01-23 00:15

I use Spring WebFlux (Project Reactor) and I\'m facing the following problem: I have to get some data from db to use them to call another service - everything in one stream. How

相关标签:
1条回答
  • 2021-01-23 00:41

    Stop breaking the chain

    This is a pure function it returns something, and always returns the same something whatever we give it. It has no side effect.

    public Mono<Integer> fooBar(int number) {
        return Mono.just(number);
    }
    

    we can call it and chain on, because it returns something.

    foobar(5).flatMap(number -> { ... }).subscribe();
    

    This is a non pure function, we can't chain on, we are breaking the chain. We can't subscribe, and nothing happens until we subscribe.

    public void fooBar(int number) {
        Mono.just(number)
    }
    
    fooBar(5).subscribe(); // compiler error
    

    but i want a void function, i want, i want i want.... wuuaaa wuaaaa

    We always need something to be returned so that we can trigger the next part in the chain. How else would the program know when to run the next section? But lets say we want to ignore the return value and just trigger the next part. Well we can then return a Mono<Void>.

    public Mono<Void> fooBar(int number) {
        System.out.println("Number: " + number);
        return Mono.empty();
    }
    
    foobar(5).subscribe(); // Will work we have not broken the chain
    

    your example:

    private void createObjAndCallAnotherService(Prot prot){
        myRepository.findById( ... ) // breaking the chain, no return
    }
    

    And some other tips:

    • Name your objects correctly not MyObj and saveObj, myRepository
    • Avoid long names createObjAndCallAnotherService
    • Follow single responsibility createObjAndCallAnotherService this is doing 2 things, hence the name.
    • Create private functions, or helper functions to make your code more readable don't inline everything.

    UPDATE

    You are still making the same misstake.

    commandFactory // Here you are breaking the chain because you are ignoring the return type
        .get()
        .createCommandFromProtection(protection)
        .subscribe(command -> commandControllerApi.createNewCommand(command)
    .subscribe()); // DONT SUBSCRIBE you are not the consumer, the client that initiated the call is the subscriber
    return Mono.just(protection);
    

    What you want to do is:

    return commandFactory.get()
        .createCommandFrom(protection)
        .flatMap(command -> commandControllerApi.createNewCommand(command))
        .thenReturn(protection);
    

    Stop breaking the chain, and don't subscribe unless your service is the final consumer, or the one initiating a call.

    0 讨论(0)
提交回复
热议问题