alizeyn
alizeyn

Reputation: 2420

Return null or something nullable from lambda in transformation method WebFlux

In a Spring WebFlux chain I use a map operation which sometimes may return null and I get a warning: Return null or something nullable from lambda in transformation method. I believe when data is null it doesn't actually map input to null but it will raise an exception instead.

What is the best way to handle the scenario ?

Map method which is nullable:

public Pojo parseJson(String json) {
    try {
        // parse 
        return pojo;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

My reactive chain:

public Mono<Pojo> query(long id) {

    Integer value = idMapper.getValue(id);

    if (value != null) {
        return repo.query(value)

                        Parse Method
                             |
                             v
                .map(this::parse);
    }
    return null;
}

Upvotes: 10

Views: 13934

Answers (1)

Toerktumlare
Toerktumlare

Reputation: 14812

When working in a functional/reactive world you should try to avoid all null checks and try to never return null from any methods.

Instead return Optional<T> when there is a risk for a null return, and return Mono.error when there is an error in a function that returns Mono. Or return Mono.empty if you just want to skip returning something.

By using optional you can rewrite the code to something much cleaner.

public Optional<Pojo> parseJson(String json) {
    // Return an optional if there is risk for a null.
    return Optional.ofNullable(new Pojo());
}

private final IdMapper idMapper = new IdMapper();
private final Repo repo = new Repo();

public Mono<Pojo> query(long id) {

    // By returning an optional from the idMapper 
    // you can chain on and avoid null checks.
    return idMapper.getValue(id).map(integer -> repo.query(integer)
            .map(s -> parseJson(s).map(Mono::just)
                    .orElse(Mono.empty())))
            .orElse(Mono.error(() -> new NotFoundException("No Pojo with ID could be found")));
}

class Pojo {
    // Some pojo class
}

class Repo {
    public Mono<String> query(long id) {
        return Mono.just("Foo");
    }
}

class IdMapper {

    public Optional<Integer> getValue(long id) {
        // Here return an Optional instead of null!
        return Optional.of(1);
    }
}

Here I return Optionals and make decisions to either return a Mono.empty or a Mono.error depending on what happens.

Upvotes: 19

Related Questions