pagination or while loop using recursion
Pagination is very common scenario in APIs nowadays. If you need to interact with an API that has pagination, you will need to build a logic where you can call the API again and again until you have reached end of the page.
This is like recursion but with modified parameters. However, recursion has some disadvantages if it exceeds some certain limit in mule, you might get into stack issues. But if you know that there are a definite set of pages which you are dealing with then recursion can come handy. This can also help you building while loop scenarios in MuleSoft.
Here we are trying to call an API (which has pagination built) to get all the blogs.
- At first the API is called without any pagination parameters as you will not be aware if that API supports pagination or not.
- Choice router will help us in deciding if we need to further call the API for more records.
- The “set variable page_number” will change the request parameter (with new page parameters) when calling the subsequent API call (call mulesy api endpoint)
- The flow “process-get-blogs-SubFlow” calls itself to get more records further with modified parameters.
Code Snippet of the flow :
<?xml version="1.0" encoding="UTF-8"?> <mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd"> <sub-flow name="process-get-blogs-SubFlow" doc:id="e6797411-50ce-4a76-80fa-6390475d2d71"> <ee:transform doc:name="create-http-variable" doc:id="da4baa5d-f400-4882-98f8-51494e49825b"> <ee:message/> <ee:variables> <ee:set-variable variableName="http"><![CDATA[%dw 2.0 output application/json --- { headers: { }, uriparameters: { }, queryparameters: { limit: 50, (page_number : vars.page_number) if vars.page_number != null }, path: "/api/v1/mulesy/blogs", method: "GET", request: { } } ]]></ee:set-variable> </ee:variables> </ee:transform> <flow-ref doc:name="call mulesy api endpoint" doc:id="f83dd5ee-c18a-4ec7-8474-f1b729c94aa6" name="mulesy-api-SubFlow1"/> <ee:transform doc:name="save-final-results" doc:id="352d5f4e-1a5b-434f-8f04-a426ff754d62"> <ee:message/> <ee:variables> <ee:set-variable variableName="blogs_temp"><![CDATA[%dw 2.0 output application/java --- vars.blogs_temp default [] ++ payload.blogs]]></ee:set-variable> </ee:variables> </ee:transform> <choice doc:name="check if further pages exists" doc:id="5ba30867-5f55-4ad3-b437-7529b822df0a"> <when expression='#[attributes.header.pagination == true]'> <ee:transform doc:name="set variable page_number" doc:id="77f38c6a-f84d-4db4-9e7c-42be82c361ea"> <ee:message/> <ee:variables> <ee:set-variable variableName="page_number"><![CDATA[%dw 2.0 import * from dw::core::URL output application/json --- attributes.headers.page_number]]></ee:set-variable> </ee:variables> </ee:transform> <flow-ref doc:name="process-get-blogs-SubFlow" doc:id="a0369b98-9d0d-4ba6-a9bb-0e7cbe83c2e0" name="process-get-blogs-SubFlow"/> </when> <otherwise> <logger level="INFO" doc:name="Logger" doc:id="98f3f8bb-8eda-4132-b26f-cb58fd9711b8" message="all pages retrieved"/> </otherwise> </choice> </sub-flow> <sub-flow name="mulesy-api-SubFlow1" doc:id="6f656a6f-f457-49f4-b1a9-f2d236314936"> <http:request method="#[vars.http.method]" doc:name="call mulesy api endpoint" doc:id="74d3bbb5-1bf8-4f9f-8bf1-2ed5ef885616" config-ref="HTTP_Request_configuration" path="#[vars.http.path]" sendCorrelationId="ALWAYS" responseTimeout="${http.response.timeout}"> <http:body><![CDATA[#[vars.http.request]]]></http:body> <http:headers><![CDATA[#[output application/java --- vars.http.headers]]]></http:headers> <http:uri-params><![CDATA[#[output application/java --- vars.http.uriparameters]]]></http:uri-params> <http:query-params><![CDATA[#[output application/java --- vars.http.queryparameters]]]></http:query-params> </http:request> </sub-flow> </mule>
Hi
There is a much better solution, using TCO and Lookup in Dataweave as I explain at my blog (in French and in English):
https://ms-data-beach.blogspot.com/2024/02/la-boucle-while.html