Query Utilities
Essential knowledge
Intended Audience:
Technical User
Author:
Kirill Gaiduk
Changed on:
10 July 2025
Overview
The`QueryUtils` class in the `util-core` bundle offers a set of functions to simplify GraphQL queries from within your Rules. These helpers make it easier to work with query results and handle common data structures like paginated connections.Key points
- Type-Safe Queries: The
`query`method is a wrapper that eliminates the need to manually cast GraphQL responses to the correct type, making your code cleaner and safer. - Simplified Connections:
`connectionToList`is a powerful helper that converts a standard GraphQL "connection" (with its`edges`and`nodes`) into a simple`List`of objects, removing a significant amount of boilerplate code. - Inline Transformation:
`connectionToList`can also accept a function, allowing you to transform the list of GraphQL nodes into a list of your own domain objects (POJOs) in a single operation.
Core Methods
`query`
This method is a wrapper around the standard `context.api().query()` method. Its main advantage is that it is properly generified, meaning you don't need to manually cast the response to the correct `Operation.Data` type.1import static com.fluentcommerce.util.core.QueryUtils.query;
2
3// ...
4
5// The 'query' helper automatically returns the correct response type,
6// so no casting is needed.
7GetMyEntityQuery.Data response = query(
8 context,
9 GetMyEntityQuery.builder()
10 .id(context.getEvent().getEntityId())
11 .build()
12);
13
14// You can now access the response data directly
15String status = response.entity().status();`connectionToList`
This utility is designed to solve a common problem when working with GraphQL: converting a paginated "connection" into a `List`. A connection is a standard GraphQL pattern for representing one-to-many relationships (like an order having multiple items) that includes pagination cursors and edges.The `connectionToList` method automatically extracts the `node` from each `edge` in the connection and returns an `ImmutableList` of nodes.When using this method, make sure that the GraphQL query aliases for the connection fields are correctly named or suffixed with "edge" and "node." If you have multiple connections in a single query, Apollo might automatically name them as `Node1`, `Node2`, and so on, which can cause issues. To prevent this, explicitly alias each connection with meaningful names like `itemNode` or `fulfilmentNode`.An overloaded method provides a second boolean which controls error handling: `true`will throw an exception if the connection is invalid`false`will simply return an empty list in those cases.
`GetOrderByIdQuery` that returns an order with a connection of `items`. The response structure might look like this:1{
2 "data": {
3 "order": {
4 "id": "123",
5 "items": {
6 "edges": [
7 { "node": { "id": "item-A", "ref": "SKU-A" } },
8 { "node": { "id": "item-B", "ref": "SKU-B" } }
9 ]
10 }
11 }
12 }
13}`QueryUtils`, it's a single line:1import com.fluentcommerce.util.core.QueryUtils;
2import com.google.common.collect.ImmutableList;
3
4// ...
5
6// Assume 'response' is the result from the GetOrderByIdQuery
7GetOrderByIdQuery.Items itemsConnection = response.order().items();
8
9// Convert the entire connection to a simple list of item nodes
10ImmutableList<GetOrderByIdQuery.Node> items = QueryUtils.connectionToList(itemsConnection);
11
12// You now have a simple list to work with
13for (GetOrderByIdQuery.Node item : items) {
14 context.action().log("Item ref: " + item.ref());
15}`connectionToList` (using a converter)
An overloaded version of `connectionToList` accepts a `Function` to convert the nodes into a different type. This is useful for mapping GraphQL response objects to your own domain models.This variant not only extracts the "node" elements from the "edge" structure but also applies a converter function (from type `T` to type `R`) to each node. As a result, it returns a list where each item is the result of applying the converter function to the original nodes.1// Convert the connection directly to a list of MyItem domain objects
2ImmutableList<MyItem> myItems = QueryUtils.connectionToList(
3 itemsConnection,
4 itemNode -> new MyItem(itemNode.id(), itemNode.ref())
5);