Fluent Commerce Logo
Docs

Dynamic Queries and Utils

Essential knowledge

Intended Audience:

Technical User

Authors:

Kirill Gaiduk, Valery Kornilovich

Changed on:

19 Mar 2026

Overview

`DynamicEntityQuery`, with the help of the `DynamicUtils` class, automatically derives the correct GraphQL query operation for the primary Entity from the `RulesetContext`. It dynamically retrieves fields related to that Entity, removing the need for pre-compiled queries while preserving type safety and performance.

Key points

  • Runtime Query Generation: Automatically builds GraphQL queries at runtime based on entity context, eliminating pre-compiled queries.
  • Dual Usage Patterns: Type-based mapping with POJO classes for strong typing, or path-based queries for maximum flexibility.
  • Universal & Validated: Works across different entity types with automatic schema validation and connection pattern handling.
  • Flexible Access: Results accessible as typed objects, JsonNode, or flattened maps with Lombok integration.
  • Connection Handling: Built-in support for paginated connections with automatic pagination handling via `queryList()` methods.
  • Dynamic Mutations: Update entity properties dynamically using key-value pairs without pre-compiled mutation queries.
  • Unified Data Access: `getJsonPath()` method provides unified access to both event and entity data using consistent path syntax.

Key Advantages Over Traditional Apollo Queries

  • One Query, Many Types
    `DynamicEntityQuery` allows a single query to be applied across different entities, especially those with common interfaces, removing the need for individual, pre-compiled queries for each entity type. This flexibility reduces the need for branching logic within rules, which can be a major source of inefficiency.
    For example, the `ChangeStateGQL` rule became outdated quickly whenever new entity types were introduced. Therefore the `SetState` was introduced which is entity type agnostic and therefore provides more flexibility.
  • Runtime Query Building
    `DynamicEntityQuery` supports building queries at runtime rather than relying solely on pre-compilation. This means that a rule can dynamically determine which data it requires based on parameters or other runtime information.
  • Reduced Maintenance
    No need for individual pre-compiled queries for each entity type, eliminating the overhead of maintaining separate query files and reducing the risk of inconsistencies.

Core Components

  • `DynamicUtils`: The main utility class that provides a simplified API for all dynamic operations:
    • Query Operations: Type-based and path-based querying
    • Connection Handling: Paginated data retrieval
    • Mutations: Dynamic entity updates
    • Data Access: Unified event and entity data access
  • `DynamicEntityQuery`: The underlying query builder that generates GraphQL queries from:
    • POJO class definitions (type-based)
    • Path specifications (path-based)
    • Query parameters and filters
  • `DynamicDataTypes`: Provides the response handling mechanisms:
    • `QueryDynamicData`: Wrapper for query results with type conversion
    • `QueryDynamicVariables`: Variable handling for parameterized queries

Here is a collection of common scenarios for the Dynamic Queries usage:

Type-based usage

To generate a dynamic query from a strongly typed Java class, `DynamicUtils.query()` recursively derives a query based on the fields defined within the class and then executes the query. The resulting object is automatically marshaled back into the same class.

Example 1: Entity Fetching Query

Example 2: Fulfillment Fetching Query

Benefits:
  • Type Safety: Strongly typed results with automatic marshaling
  • Lombok Integration: Use Lombok to reduce boilerplate code
  • Field Mapping: Only the fields within the class are used for marshaling
  • Simplified API: `DynamicUtils.query()` handles the complexity of query execution and type conversion

Alternative Direct API Usage

If you need more control over the query execution, you can use the direct API:

Path-based usage

Path-based queries allow you to define your query as a series of strings, where each string represents a dot-separated path through the data graph. This approach is highly flexible and enables the creation of rules that adapt seamlessly to multiple entity types and fields.

Example 1: Multiple-Fields Query

These paths would generate a GraphQL query that retrieves only the specified fields:The library uses GraphQL schema introspection to ensure that each generated path aligns with valid schema fields; any invalid or mismatched paths are automatically excluded, ensuring that only valid data is queried.The resulting `DynamicEntityQuery.DynamicData` object can be accessed either as a Jackson `JsonNode` for structured JSON handling or flattened into a map of graph selectors to `JsonNode` values for quick lookup.

Example 2: Single-Field Query

You can also use `DynamicUtils.query` to retrieve a single field value directly from the entity:Benefits:
  • Automatic Connection Handling`items.product.name` automatically expands to `items.edges.node.product.name`
  • Schema Validation: Uses GraphQL introspection to ensure valid paths
  • Flexible Access: Results can be accessed as `JsonNode` or flattened map
  • Error Prevention: Invalid paths are automatically excluded

Connection Queries (Pagination)

For handling paginated connections like `items`, `fulfilments`, etc., use the `queryList()` methods:

Example 1: Specific Fulfillments Loading

Example 2: Order Fulfillments Loading

Example 3: Fulfillment Articles Loading

Dynamic Mutations

The `DynamicUtils.mutate()` method allows you to update entity properties dynamically:

JSON Path Access

The `getJsonPath()` method allows you to access data from either the event or entity using a unified path syntax:

Complete Examples

Example 1: Attribute Checking Rule

This rule loads attributes associated with an order and checks if a specified attribute exists:

Example 2: Flexible Property Comparison

This rule compares a parameter value against an arbitrary field of the primary entity: