Optional<> fields in new Java API

The new Java SDK has practically all fields has Optional<> rather than the previous String, int, etc. This makes it much more cumbersome to work with - e.g. location.name().orElse(null).
Is there some feature in the SDK or in Java that makes this easier to deal with or must we do .get()/.orElse() on each field?

A real example:

RefundPaymentResponse resp = ...;
double refunded = resp.getRefund().get().getAmountMoney().getAmount().get()/100.0;

:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Retrieve Refunds
Square Java SDK Quickstart
Working with Monetary Amounts in Square APIs

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

The use of Optional<> in Java is a way to help prevent NullPointerExceptions by forcing you to think about the case where a value might not be present. It’s a form of making your code safer and more expressive.

In your example, you’re chaining multiple get() calls together. This could potentially lead to a NullPointerException if one of the intermediate steps returns an empty Optional.

To make this safer, you could use the map() function that’s available on Optional. This allows you to apply a function to the value inside the Optional, if it’s present. If the Optional is empty, map() just returns an empty Optional.

Here’s how you could rewrite your example:

RefundPaymentResponse resp = ...;
Optional<Double> refunded = resp.getRefund()
    .flatMap(refund -> refund.getAmountMoney())
    .flatMap(money -> money.getAmount())
    .map(amount -> amount / 100.0);

In this code, each flatMap() call is used to “unwrap” an Optional. If the Optional is empty, the rest of the chain is skipped and an empty Optional is returned. The final map() call converts the amount to a double, if it’s present.

This code will give you an Optional for the refunded amount. If any of the fields in the chain were missing, you’ll just get an empty Optional. You can then decide what to do with this Optional. For example, you could use orElse() to provide a default value if the Optional is empty:

double refundedAmount = refunded.orElse(0.0);

This approach makes it clear that the refunded amount might not always be present, and forces you to handle this case.

This answer was reviewed by @Bryan-Square.

Thanks for responding.

Can we assume that methods that return Optional<> will never return null?

i.e. getAmountMoney() == null will never be true; instead only need to check for getAmountMoney().isPresent() or .isEmpty() ?

Yes, you can assume that methods returning Optional<> will not return null. Instead, they will return an Optional object, which may either be empty or contain a value. Therefore, you should use isPresent() or isEmpty() to check for the presence of a value, rather than checking for null.

This design choice helps prevent NullPointerExceptions and encourages you to think about how to handle cases where data might not be available. Using methods like map(), flatMap(), and orElse() allows you to work with these values more fluidly and safely. :slight_smile: