Repository navigation
While, Do-while loop implementation for fetching paginated data from an API #1096
Description
What would you like to be added?
Support for while or do-while loop constructs to simplify workflows that need to fetch paginated data from APIs until a condition is met (e.g., no more pages to fetch).
Proposal(s):
Currently, implementing workflows that require repetitive API calls until a condition is met (e.g., while nextPageToken is present) is cumbersome and verbose using the existing specification. There is no native support for loop constructs that check a condition after each iteration (i.e., a do-while pattern).
Proposal:
- Introduce a native while or do-while loop construct within the Serverless Workflow specification.
- Support a conditional expression (JQ) that evaluates whether the loop should continue.
- Allow a loopBody or array of steps to be executed within the loop.
- Optional: support max iterations to prevent infinite loops.
Example syntax (pseudo-DSL):
document:
dsl: '1.0.0'
namespace: test
name: paginated-fetch-example
version: '0.1.0'
do:
- fetchPaginatedData:
while: .hasNextPage == true
postConditionCheck: false // Enables do-while
maxIterations: 100
do:
- fetchPage:
call: getPageData
input:
pageToken: .nextPageToken
output: .fetchedData
- accumulateData:
run: mergeResults
input:
newData: .fetchedData
existingData: .accumulatedResults
output: .accumulatedResults
Alternative(s):
Currently, the same can be achieved by:
- Manually chaining states with
transitionand using aswitchto re-enter a state based on a condition. - Using recursion with
workflow calls, which increases complexity and reduces readability. - Implementing a custom function or orchestrator outside of the workflow itself.
These approaches are harder to read, maintain, and error-prone when retry logic and timeouts are introduced.
Additional info:
This feature would greatly improve:
- Workflows that deal with pagination (API data fetching, batch processing).
- Polling use cases where the data becomes available over time.
- Any retry-until-success or loop-until-condition patterns.
Let me know if you'd like me to open a PR to help explore this idea! Or do you think this can be achieved with current For loop? @ricardozanini @cdavernas
Community Notes
- Please vote by adding a 👍 reaction to the feature to help us prioritize.
- If you are interested to work on this feature, please leave a comment.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
nyamathshaik commentedon Apr 14, 2025
However, It appears that the current
fortask can be utilized as a loop, allowing a For task to operate as a traditional while loop in Serverless Workflow.By setting the
for.inproperty of a For task to an empty collection, thewhileproperty takes over as the primary control mechanism for the loop, facilitating the use of bothwhileanddo-whileloop patterns within Serverless Workflows.Example:
Example:
nyamathshaik commentedon Apr 14, 2025
May I know if
foris mandatory or can we get it ofAccording to typescript SDK it's optional, but its no-where that's mentioned in the specs, can you clarify please?
https://github.com/serverlessworkflow/sdk-typescript/blob/main/src/lib/generated/definitions/specification.ts#L252
cdavernas commentedon Apr 14, 2025
@nyamathshaik Yes,
foris mandatory, and also serves as a discriminator. In addition, your suggestion would not work because the enumeration would stop before evaluating thewhilecondition, as the array is empty.whilein that context is an exit condition, not a continuation one, in which case it would create many unpleasant side effects (one being a null ref for enumerated item).Therefore, you initial proposal looks to me to be the most adequate, and would also restore a construct we had in previous versions.
nyamathshaik commentedon Apr 14, 2025
@cdavernas Thank you for the feedback. I was considering something along the lines of the following, but I am still open to suggestions. Please review it and let me know if it looks good.
Benefits of Proposed Approach
This proposed solution provides a structured approach to implementing loop tasks while maintaining compatibility with Serverless Workflow specifications.
cdavernas commentedon Apr 14, 2025
@nyamathshaik First of all, thanks for your awesome work!
Second, I have a couple of remarks regarding the proposal you made in related PR:
whilekeyword will need to change, either in the task you propose to add, or in thefortask, or discrimination will no longer be (easily) possible (i.e. check for presence ofwhilekeyword, which as a primary identifier must not be use by any other task)postConditionCheckandmaxIterationsterminology, which goes against the design guidelines. I'm convinced we can come up with imperative, actionable, single words names instead!nyamathshaik commentedon Apr 14, 2025
@cdavernas Thanks a lot for the feedback and kind words! 🙌 Really appreciate you taking the time to review the proposal.
Totally hear you on the concerns around the
whilekeyword clash and the naming ofpostConditionCheckandmaxIterations.For the keyword conflict: I’m happy to revise the structure to avoid any ambiguity with
fortasks. Would something like below look good?Open to suggestions! I'm happy to iterate further on the proposal based on whatever naming conventions or structural guidance the maintainers feel would fit best.
Looking forward to your thoughts!
nyamathshaik commentedon Apr 14, 2025
or how about just simply renaming the initial proposal to below :
ricardozanini commentedon Apr 14, 2025
Why not:
And
The challenge is to interpret this in the JSON Schema.
Essentially, you want a
forwithoutin, correct?ricardozanini commentedon Apr 14, 2025
We can add the
limitkeyword, no problem. But yes, we must avoid camel-cased and composition words.ricardozanini commentedon Apr 14, 2025
The first is a
dotask with an optionalwhileparameter. The other is awhiletask. I think we can accommodate this in the JSON schema with backwards comp for1.1.0.nyamathshaik commentedon Apr 14, 2025
Thanks for reviewing @ricardozanini JSON Schema doesn’t support positional logic. So I don't think comment actually works. (i.e., if while appears before, interpret it one way; if after, interpret differently).
Also, this creates more Ambiguity in Semantics (while appearing before or after do: changes the behavior).
nyamathshaik commentedon Apr 14, 2025
That said, I am still aligned with below :
Approach 1:
Approach 2:
Please let me know if you have any further suggestions, or an entire new suggestion is fine too. So that we can agree upon the final solution and I can work on raising a PR.
@ricardozanini @cdavernas
62 remaining items
github-actions commentedon May 16, 2026
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
ricardozanini commentedon Jul 23, 2026
After reviewing this discussion, I think the existing
if+thenmechanism already covers bothwhileanddo-whilepatterns without requiring new task types. Here's how:While loop (condition checked before each iteration)
The
ifguards execution — when.counter < 5is false, the task is skipped and flow continues toafterLoop. When true,setruns andthen: loopjumps back to itself.Do-while loop (body runs at least once, condition checked after)
Here
loopalways executes (noifguard), thencheckevaluates the condition. If true, it jumps back toloop. If false,checkis skipped and flow falls through toafterLoop.Given that both patterns work today with the current spec, I'd suggest we document these as "how-to" patterns (as @geomagilles also suggested) rather than introduce new task types. Adding
while/repeattasks is a permanent commitment that would impact all SDKs, and the benefit over theif+thenapproach doesn't seem to justify the complexity — especially since introducing new discriminator keywords risks collisions with the existingfor.whileproperty.If the community feels strongly about dedicated loop constructs in the future, we can revisit, but for now documenting these patterns should address the original use case.
@nyamathshaik would you be interested in contributing a "how-to" guide or examples for these patterns instead?
fjtirado commentedon Jul 24, 2026
@ricardozanini I agree with the rational but if-then pattern currently has a side effect in task json pointer. In a for, every executed task has a different jsopointer, while if-then repeats the same jsonpointer several times (jsonpointer is part of the life cycle cloud event, so this has to be adressed somehow in the spec, either mentioning that when using this pattern the jsonpointer of the task is repeated or by introducing a way to generate different json pointers)
ricardozanini commentedon Jul 24, 2026
@fjtirado great catch! Yes, indeed, in the lifecycle event, a monitoring actor will see repeatable tasks without an
indexwe have infor.Alternatively, I was thinking of a workaround where you add a single task before
for, so you guarantee it executes once. I think we mentioned this alternative in this thread already.Nevertheless, I think it's not worth a new task for this use case given we already have alternatives to tackle this problem.