Uma função de transformação do reator que criei não dá o mesmo resultado quando extraio as etapas individuais e as executo separadamente.
Tenho registro DTO que contém uma Lista do tipo Preço.
public record CarrierDto(MetaData metaData, List<Daily> dailySeries) {
public record MetaData(String name, String information) {};
public record Daily(String date, Integer price) {};
}
Quero extrair de Mono<CarrierDto>
a Flux<Daily>
e depois transformá-lo em Flux<Price>
.
@Table("price")
public record Price (
@Column("p_date") String date,
@Column("p_price") Integer price) {
}
Para fazer essa transformação eu tenho essa função:
static Function<Mono<CarrierDto>, Flux<Price>> transform = carrierDtoMono ->
carrierDtoMono.map(CarrierDto::dailySeries)
.flatMapMany(Flux::fromIterable)
.map(daily -> new Price(daily.date(), daily.price()));
No entanto, quando tento usar esta função, apenas um preço é fornecido no momento da assinatura. Se eu extrair cada etapa individual e executar TODOS os preços serão fornecidos. Por exemplo, com esta classe de teste:
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class TestMain {
static Function<Mono<CarrierDto>, Flux<Price>> transform = carrierDtoMono ->
carrierDtoMono.map(CarrierDto::dailySeries)
.flatMapMany(Flux::fromIterable)
.map(daily -> new Price(daily.date(), daily.price()));
public static void main(String[] args) {
final CarrierDto dto = new CarrierDto(new CarrierDto.MetaData("Test", "Test information"),
Arrays.asList(new CarrierDto.Daily("2023-01-01", 100),
new CarrierDto.Daily("2023-01-02", 101),
new CarrierDto.Daily("2023-01-03", 102),
new CarrierDto.Daily("2023-01-04", 103)));
System.out.println("Using Transform function.");
Mono.just(dto)
.transform(transform)
.subscribe(price -> System.out.println(String.format("Date: %s Price: %d", price.date(), price.price())));
System.out.println("Without transform function.");
final Mono<List<CarrierDto.Daily>> monoDailySeries = Mono.just(dto).map(CarrierDto::dailySeries);
final Flux<CarrierDto.Daily> dailyFlux = monoDailySeries.flatMapMany(Flux::fromIterable);
final Flux<Price> priceFlux = dailyFlux.map(daily -> new Price(daily.date(), daily.price()));
priceFlux.subscribe(price -> System.out.println(String.format("Date: %s Price: %d", price.date(), price.price())));
}
}
Dá o resultado:
Using Transform function.
Date: 2023-01-01 Price: 100
Without transform function.
Date: 2023-01-01 Price: 100
Date: 2023-01-02 Price: 101
Date: 2023-01-03 Price: 102
Date: 2023-01-04 Price: 103
Por que o resultado é diferente?
Isso porque o
transformer
inMono
produz um newMono
, ou seja, solicitando apenas o primeiro item do Publisher.Internamente possui:
Sugiro começar com Flux (ou converter Mono em Flux). Como no seu exemplo: