From 757c6136d4355beca963612819e0e71ee649ce5b Mon Sep 17 00:00:00 2001 From: Matheus Cruz Date: Mon, 4 May 2026 18:46:07 -0300 Subject: [PATCH] Document withUniqueId overloads Signed-off-by: Matheus Cruz --- .../fluent/func/dsl/FuncDSL.java | 180 ++++++++++++++++-- 1 file changed, 168 insertions(+), 12 deletions(-) diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java index cbe692b0a..79dc2c5b1 100644 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java +++ b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java @@ -479,24 +479,88 @@ static String defaultUniqueId(WorkflowContextData wctx, TaskContextData tctx) { } /** - * Build a call step for functions that expect a composite "unique id" as the first parameter. - * This id is derived from the workflow instance id and the task definition position, encoded as a - * JSON pointer. + * Build a named call step for functions that expect a composite "unique id" as the first + * parameter. This id is derived from the workflow instance id and the task definition position, + * encoded as a JSON pointer. * - *

Signature expected: {@code (uniqueId, payload) -> result} + *

The unique ID follows the pattern: {@code "-"} where the JSON + * pointer represents the task's position in the workflow definition. + * + *

This overload requires explicit input class and infers the output type from the function + * signature. + * + *

Signature expected: {@code (uniqueId, payload) -> result} + * + *

Example: + * + *

{@code
+   * tasks(
+   *   withUniqueId("processOrder",
+   *     (String uniqueId, OrderRequest order) -> {
+   *       // Use uniqueId for stateful operations (e.g., database keys, cache entries)
+   *       return orderService.process(uniqueId, order);
+   *     },
+   *     OrderRequest.class
+   *   )
+   * );
+   * }
* * @param name task name (or {@code null} for an anonymous task) - * @param fn unique-id-aware function - * @param in payload input class + * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result + * @param in payload input class for type-safe conversion * @param input type * @param result type - * @return a call step + * @return a named call step that can be chained with additional configurations + * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) + * @see #withUniqueId(String, UniqueIdBiFunction) + * @see #withUniqueId(UniqueIdBiFunction, Class) + * @see #withUniqueId(UniqueIdBiFunction) */ public static FuncCallStep withUniqueId( String name, UniqueIdBiFunction fn, Class in) { return withUniqueId(name, fn, in, ReflectionUtils.inferResultType(fn)); } + /** + * Build a named call step for functions that expect a composite "unique id" as the first + * parameter, with explicit input and output type classes. + * + *

The unique ID follows the pattern: {@code "-"} where the JSON + * pointer represents the task's position in the workflow definition. + * + *

This overload provides complete control over type conversion by explicitly specifying both + * input and output classes. Use this when automatic type inference is not sufficient or when you + * need to ensure specific serialization/deserialization behavior. + * + *

Signature expected: {@code (uniqueId, payload) -> result} + * + *

Example: + * + *

{@code
+   * tasks(
+   *   withUniqueId("enrichData",
+   *     (String uniqueId, Map input) -> {
+   *       // Process and transform with explicit types
+   *       return dataEnricher.enrich(uniqueId, input);
+   *     },
+   *     Map.class,
+   *     EnrichedData.class
+   *   )
+   * );
+   * }
+ * + * @param name task name (or {@code null} for an anonymous task) + * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result + * @param in payload input class for type-safe conversion + * @param out result output class for type-safe conversion + * @param input type + * @param result type + * @return a named call step that can be chained with additional configurations + * @see #withUniqueId(String, UniqueIdBiFunction, Class) + * @see #withUniqueId(String, UniqueIdBiFunction) + * @see #withUniqueId(UniqueIdBiFunction, Class) + * @see #withUniqueId(UniqueIdBiFunction) + */ public static FuncCallStep withUniqueId( String name, UniqueIdBiFunction fn, Class in, Class out) { FilterFunction jff = @@ -504,24 +568,116 @@ public static FuncCallStep withUniqueId( return new FuncCallStep<>(name, jff, in, out); } + /** + * Build a named call step for functions that expect a composite "unique id" as the first + * parameter, with automatic type inference. + * + *

The unique ID follows the pattern: {@code "-"} where the JSON + * pointer represents the task's position in the workflow definition. + * + *

This overload uses reflection to automatically infer both input and output types from the + * {@link UniqueIdBiFunction} interface. This is the most concise variant but requires the + * function to be serializable for type inference to work. + * + *

Signature expected: {@code (uniqueId, payload) -> result} + * + *

Example: + * + *

{@code
+   * tasks(
+   *   withUniqueId("cacheResult",
+   *     (String uniqueId, ProcessRequest req) -> {
+   *       cache.store(uniqueId, req);
+   *       return processor.handle(req);
+   *     }
+   *   )
+   * );
+   * }
+ * + * @param name task name (or {@code null} for an anonymous task) + * @param fn unique-id-aware function with serializable signature for type inference + * @param input type (inferred automatically) + * @param result type (inferred automatically) + * @return a named call step that can be chained with additional configurations + * @see #withUniqueId(String, UniqueIdBiFunction, Class) + * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) + * @see #withUniqueId(UniqueIdBiFunction) + */ public static FuncCallStep withUniqueId(String name, UniqueIdBiFunction fn) { return withUniqueId(name, fn, ReflectionUtils.inferInputType(fn)); } /** - * Variant of {@link #withUniqueId(String, UniqueIdBiFunction, Class)} without an explicit task - * name. + * Build an unnamed call step for functions that expect a composite "unique id" as the first + * parameter. * - * @param fn unique-id-aware function - * @param in payload input class + *

The unique ID follows the pattern: {@code "-"} where the JSON + * pointer represents the task's position in the workflow definition. + * + *

This overload requires an explicit input class and infers the output type from the function + * signature. Use this when you don't need to assign a specific task name. + * + *

Signature expected: {@code (uniqueId, payload) -> result} + * + *

Example: + * + *

{@code
+   * tasks(
+   *   withUniqueId(
+   *     (String uniqueId, CustomerData data) -> {
+   *       logger.log("Processing " + uniqueId);
+   *       return customerProcessor.process(data);
+   *     },
+   *     CustomerData.class
+   *   )
+   * );
+   * }
+ * + * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result + * @param in payload input class for type-safe conversion * @param input type * @param result type - * @return a call step + * @return an unnamed call step that can be chained with additional configurations + * @see #withUniqueId(String, UniqueIdBiFunction, Class) + * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) + * @see #withUniqueId(UniqueIdBiFunction) */ public static FuncCallStep withUniqueId(UniqueIdBiFunction fn, Class in) { return withUniqueId(null, fn, in); } + /** + * Build an unnamed call step for functions that expect a composite "unique id" as the first + * parameter, with automatic type inference. + * + *

The unique ID follows the pattern: {@code "-"} where the JSON + * pointer represents the task's position in the workflow definition. + * + *

This is the most concise overload, using reflection to automatically infer both input and + * output types. It creates an anonymous task, which is useful for quick inline operations. + * + *

Signature expected: {@code (uniqueId, payload) -> result} + * + *

Example: + * + *

{@code
+   * tasks(
+   *   withUniqueId((String uniqueId, String input) -> {
+   *     // Quick stateful operation with unique ID
+   *     stateManager.update(uniqueId, input);
+   *     return input.toUpperCase();
+   *   })
+   * );
+   * }
+ * + * @param fn unique-id-aware function with serializable signature for type inference + * @param input type (inferred automatically) + * @param result type (inferred automatically) + * @return an unnamed call step that can be chained with additional configurations + * @see #withUniqueId(String, UniqueIdBiFunction) + * @see #withUniqueId(UniqueIdBiFunction, Class) + * @see #withUniqueId(String, UniqueIdBiFunction, Class) + */ public static FuncCallStep withUniqueId(UniqueIdBiFunction fn) { return withUniqueId(null, fn, ReflectionUtils.inferInputType(fn)); }