Home > Enterprise >  how to return a query mono with the code below with java reactor
how to return a query mono with the code below with java reactor

Time:08-26

Imagine that I have several filters and I need several if to validate if the value is present, and if it is, I add a criteria each time it is present and at the end of the flow I return a query.

I would then need to go through each of the filters, see if the value is present and then add a criterion.

How would I do this without using if and using only Java's Reactor powers?

I can use filter, map, filterWhen, zipWhen etc.

private Mono<Query> createQueryWithFilters(Filters filters) {
    Criteria criteria = new Criteria();
    Query query = new Query();

    if (filters.getName().isPresent()) {
        query.addCriteria(criteria.and("name")
                .regex(filters.getName().get()));
    }

    if (filters.getAge().isPresent()) {
        query.addCriteria(criteria.and("age")
                .regex(filters.getAge().get()));
    }
    
    return Mono.just(query);
}

In the code above I want to return without using if and I would like to instantiate Query() and Criteria() in the stream using Mono or Flux.

An example of coding is the one below, you can see that it is very readable and the code is more beautiful.

Code pattern example:

public Mono<TaskDTO> getTaskById(String configId, String taskId) {
    return configRepository.findById(configId)
            .switchIfEmpty(error(notFoundException(IAC_CONFIG_NOT_FOUND_ERROR_MSG)))
            .map(Config::getTasks)
            .filter(v -> v.stream().anyMatch(t -> Objects.equals(t.getId(), taskId)))
            .switchIfEmpty(error(notFoundException(IAC_TASK_NOT_FOUND_MSG)))
            .map(v -> v.stream().findAny())
            .filter(Optional::isPresent)
            .map(v -> taskConverter.convert(v.get()));
}

CodePudding user response:

You can try this solution.

        private static final Map<String, Function<Filter, Criteria>>
                FILTERS = new HashMap<>();
    
        static {
            FILTERS.put("NAME", value -> Criteria.where("name").regex((String) value.getValue()));
            FILTERS.put("AGE", value -> Criteria.where("age").is(value.getValue()));
        }
    
      public Mono<Query> createQueryWithFilters(Flux<Filter> filterFlux) {
            Criteria criteria = new Criteria();
           return Mono.from(
                   filterFlux.map(filter -> FILTERS.get(filter.getKey()).apply(filter))
                             .map(f ->  new Query(criteria.andOperator(f)))
           );
        }

Filter class

@Data
@AllArgsConstructor
public class Filter {
    String key;
    Object value;
}

Test cases

Flux<Filter> filterFlux = Flux.just(new Filter("NAME", "john"), new Filter("AGE", 19));

createQueryWithFilters(filterFlux)
        .subscribe(val -> System.out.println(val.toString()));
  • Related