Hi Square Team,
I am preparing to upgrade the Square Java SDK from version 40.1.0.20240604 to 44.2.0.20250521.
However, I’ve noticed that all the get
methods now return Optional<T>
, requiring me to unwrap the Optional<T>
each time to access the actual value. This significantly increases the verbosity of the code and is quite painful to work with during integration.
Could you please advise:
- Is there a more convenient or recommended way to use the SDK to avoid repetitive
Optional
unwrapping in our codebase?
- If possible, could you please share the reasoning behind the decision to change all properties to return
Optional<T>
in the new SDK version?
Understanding the design intention will help us better align our integration practices with the SDK’s direction.
Thank you very much for your support!
Best regards,
Murphy
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
Common Square API Patterns
Square Java SDK Quickstart
Versioning in the Square API
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.
Hey @murphyzhang! We’d recommend using the map
function instead of an isPresent
and get
check to simplify this:
foo.map(value => {})
As far as reasoning goes, returning Optional
lowers the likelihood of runtime exceptions due to null values and enforces null safety.
Thank you for explaining how to work with Optional<T>
in the new SDK.
However, I’m still having difficulty understanding one design aspect:
With CatalogObject
, I can no longer directly get the id
but instead need to retrieve a nested child object to get the id
.
public static String getId(CatalogObject c) {
if (c.isItem()) return c.getItem().get().getId();
if (c.isItemVariation()) return c.getItemVariation().get().getId();
if (c.isTax()) return c.getTax().get().getId();
if (c.isCategory()) return c.getCategory().flatMap(CatalogObjectCategory::getId).get();
if (c.isModifierList()) return c.getModifierList().get().getId();
if (c.isModifier()) return c.getModifier().get().getId();
if (c.isImage()) return c.getImage().get().getId();
return null;
}
I have an additional question regarding the new SDK design:
I don’t quite understand why the id
of a CatalogObject
is designed to be nullable. Conceptually, the id
seems like it should always exist and be non-null for a CatalogObject
.
Could you please help me understand the reasoning behind this design? It feels unintuitive compared to the previous version, and I would like to understand the benefit of this approach to better align our integration practices.
Thank you for your clarification!
Best regards,
Murphy
Hi Square Team:
If you have any updates, please feel free to let me know at any time.
Thanks,
Murphy
The CatalogObject
is a polymorphic container that can represent different types of catalog entities (items, variations, categories, etc.). Each specific type has its own properties and constraints, including how IDs are managed.
For example:
- Items have their own ID structure
- Item Variations have IDs that relate to their parent items
- Categories may have optional IDs in certain contexts
Better Pattern for ID Access
Instead of the complex conditional logic you showed, here’s a more elegant approach using the new SDK:
public static Optional<String> getId(CatalogObject catalogObject) {
// Use the top-level ID if available
return catalogObject.getId();
}
// Or if you need type-specific behavior:
public static Optional<String> getTypeSpecificId(CatalogObject catalogObject) {
return catalogObject.getId()
.or(() -> catalogObject.getItem().flatMap(CatalogItem::getId))
.or(() -> catalogObject.getItemVariation().flatMap(CatalogItemVariation::getId))
.or(() -> catalogObject.getCategory().flatMap(CatalogCategory::getId));
}
Why Nullable IDs Make Sense
The nullable design reflects real-world API scenarios:
- Draft Objects: When creating new catalog objects, they may not have IDs yet
- Partial Updates: Some API responses may include partial object data
- Different Creation Contexts: Certain catalog objects are created with server-generated IDs
- API Consistency: This aligns with how the REST API actually behaves

Thank you very much for your support. Your explanation is exceptionally clear and greatly appreciated.