Pagination tutorial

Processing large amounts of data at once can lead to errors. Learn how pagination lets users split data querying processes and retrieve a limited number of records.

When you build an integration flow, you may need to process large amounts of data. Processing all of that data at once can lead to errors such as a timeout error or an Out of Memory (OOM) error. One solution to this problem is pagination. Using pagination, you can split the data querying process into batches and retrieve only a limited number of records at a time.

In the following articles, we will guide you on how to implement pagination in a flow that makes a total migration of an HR database every day at 1 AM.

When you copy components on the Digibee Integration Platform, they are stored on your clipboard as JSON objects. The JSON object that refers to this pagination pipeline is available on the expandable block at the end of this article. You can copy and paste it into the Canvas and modify it as needed for your integration flow.

Before implementing pagination, you need to check if the API, database or web service you are querying supports pagination. If not, you can still improve the performance of your integration flow by increasing the deployment size of your pipelines.

In this example, the pagination flow is triggered every five minutes. It starts with a sequence of initial steps. After these steps, it splits into three paths, as displayed below:

Pagination pipeline
  • The flow follows the “FINISHED” path if the data migration process has already ended for the day or if it is not yet time to start it.

  • The flow follows the “EXTRACTING_DATA” path when it is time to start the data migration process and this process is not yet completed.

  • The flow follows the error path if an error occurs during the initial steps.

In the following articles, we will give you step-by-step instructions on how to build each of these paths.

Want to test this pipeline?

Copy the flowSpec below and paste it into your Canvas:

{
  "meta": {
    "trigger": {
      "position": {
        "x": 41,
        "y": 173
      }
    },
    "4ad4a7c5-7072-4722-b9a8-5a0bec9a3ee7": {
      "position": {
        "x": 173,
        "y": 173
      }
    },
    "40de968f-3ba5-4040-b549-c2baec47ac9c": {
      "position": {
        "x": 305,
        "y": 173
      }
    },
    "6068bb57-2293-485f-8b7f-7521da1f61e6": {
      "position": {
        "x": 437,
        "y": 173
      }
    },
    "f3611d47-634c-43b6-af69-92e873c3054e": {
      "position": {
        "x": 574,
        "y": 173
      }
    },
    "ecd403a3-ba82-4225-8773-ac149acab6ef": {
      "position": {
        "x": 861,
        "y": 173
      }
    },
    "beec81bb-a26e-4313-8796-c489005c901d": {
      "position": {
        "x": 998,
        "y": 173
      }
    },
    "1200afd4-cd17-47e4-92e8-d8b9f5e21d8d": {
      "position": {
        "x": 1135,
        "y": 173
      }
    },
    "61abe3ae-76f5-4aa9-a0e0-1efac1761de6": {
      "position": {
        "x": 1267,
        "y": 173
      }
    },
    "255bfcd8-01da-48a0-b87f-058f27ffcb29": {
      "position": {
        "x": 1399,
        "y": 173
      }
    },
    "14bb99b3-a847-4fce-87fc-92b0ee4f75e3": {
      "position": {
        "x": 1536,
        "y": 173
      }
    },
    "dc5d99dd-c880-4fd5-8a0f-97113e619606": {
      "position": {
        "x": 1915,
        "y": 239
      }
    },
    "a3e438f1-c3cb-47fd-a16f-058c8d452b68": {
      "position": {
        "x": 2047,
        "y": 239
      }
    },
    "d1163524-a410-4820-9649-5c43191e78cc": {
      "position": {
        "x": 2179,
        "y": 239
      }
    },
    "f236ae9e-8519-4e98-8151-0b011689e981": {
      "position": {
        "x": 2311,
        "y": 239
      }
    },
    "fe6a50ad-98c9-4c95-8da0-e1a315ca0596": {
      "position": {
        "x": 1915,
        "y": 107
      }
    },
    "247dccab-af16-401f-bc85-385d0a0d7eee": {
      "position": {
        "x": 2047,
        "y": 107
      }
    },
    "3d60fe4b-8876-4b28-b22d-0970e328967a": {
      "position": {
        "x": 2179,
        "y": 107
      }
    },
    "16735d3e-2e97-4478-be30-7648d0fa33d9": {
      "position": {
        "x": 2311,
        "y": 107
      }
    },
    "d789cf6d-7aaf-4adb-b310-d41d1e876b85": {
      "position": {
        "x": 861,
        "y": 414
      }
    },
    "b4b32036-a35b-42d7-9aef-146865104d17": {
      "position": {
        "x": 998,
        "y": 414
      }
    },
    "422e66af-dc41-4941-b7ce-5dedbc57e9f7": {
      "position": {
        "x": 1536,
        "y": 482.5
      }
    },
    "414b3c40-57fd-46d1-b396-09438646a403": {
      "position": {
        "x": 1678,
        "y": 482.5
      }
    },
    "2fcc5e50-ab4a-4003-999c-618604ead6a1": {
      "position": {
        "x": 2047,
        "y": 411.5
      }
    },
    "77a2dc52-9b57-4dad-b20e-a4ec8c8883d6": {
      "position": {
        "x": 2179,
        "y": 411.5
      }
    },
    "83d038fa-ac4d-4eff-ba4c-0a870b16440b": {
      "position": {
        "x": 2311,
        "y": 411.5
      }
    },
    "a222d3e6-0c2e-4132-bb50-c4cc94ef9195": {
      "position": {
        "x": 2047,
        "y": 548.5
      }
    },
    "ff25540c-01e6-42a4-af81-d89699a7f5d2": {
      "position": {
        "x": 2179,
        "y": 548.5
      }
    },
    "b3d89cf2-6d0c-447c-8990-fabc2a7f4ae2": {
      "position": {
        "x": 1536,
        "y": 345.5
      }
    },
    "00b06e8d-f5de-47ae-87a6-ade931cac2e6": {
      "position": {
        "x": 1678,
        "y": 345.5
      }
    },
    "318cb4a9-d653-4409-ac59-aac54b00b34b": {
      "position": {
        "x": 861,
        "y": 41
      }
    },
    "bf4a9f9e-0d6e-4775-a886-e4b321fd846f": {
      "position": {
        "x": 998,
        "y": 41
      }
    }
  },
  "flowSpec": {
    "disconnected-root:5b10222e-c930-4e9e-b584-04a07c5639b2": [
      {
        "stepName": "obtem parâmetros de paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "FIND",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "limit": "0",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "4ad4a7c5-7072-4722-b9a8-5a0bec9a3ee7",
        "type": "connector",
        "name": "object-store-connector"
      },
      {
        "stepName": "cria valores padrão",
        "params": {
          "json": "{\n \"control\":{\n \"startTimestamp\": {{ metadata.execution.startTimestamp }},\n \"limit\": {{ DEFAULT( message.data[0].limit, 500 ) }},\n \"start\": {{ DEFAULT( message.data[0].start, 0 ) }},\n \"end\": {{ DEFAULT( message.data[0].end, 500 ) }},\n \"step\": {{ DEFAULT( message.data[0].step, \"FINISHED\" ) }},\n \"nextExecutionTimestamp\": {{ message.data[0].nextExecutionTimestamp }}\n }\n}",
          "failOnError": false
        },
        "id": "40de968f-3ba5-4040-b549-c2baec47ac9c",
        "type": "connector",
        "name": "json-generator-connector"
      },
      {
        "type": "session-management",
        "stepName": "put control",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "control"
        ],
        "id": "6068bb57-2293-485f-8b7f-7521da1f61e6"
      },
      {
        "stepName": "verifica step",
        "id": "f3611d47-634c-43b6-af69-92e873c3054e",
        "type": "choice",
        "when": [
          {
            "jsonPath": "$.control.[?(@.step == 'EXTRACTING_DATA')]",
            "target": "EXTRACTING_DATA (1)"
          },
          {
            "jsonPath": "$.control.[?(@.step == 'FINISHED')]",
            "target": "FINISHED (1)"
          }
        ],
        "otherwise": "erro - step desconhecido"
      }
    ],
    "EXTRACTING_DATA (1)": [
      {
        "type": "connector",
        "name": "log-connector",
        "stepName": "Log - EXTRACTING_DATA",
        "params": {
          "logLevel": "INFO",
          "message": " EXTRACTING_DATA"
        },
        "id": "ecd403a3-ba82-4225-8773-ac149acab6ef"
      },
      {
        "stepName": "select enb_person",
        "accountLabel": "mysql-2",
        "params": {
          "url": "{{global.enablement-db-url}}",
          "sql": "select * from enb_person limit {{ message.control.start }}, {{ message.control.limit }}",
          "itemIdentifier": "codigo",
          "parallel": false,
          "blobAsFile": false,
          "clobAsFile": false,
          "failOnError": false,
          "connectionProperties": "{}",
          "keepConnection": true,
          "advanced": false,
          "dbPoolByActualConsumers": false,
          "exclusiveDbPool": false,
          "columnFromLabel": false,
          "connectionTestQuery": "",
          "onProcess": "beec81bb-a26e-4313-8796-c489005c901d-onProcessTrack",
          "onException": "beec81bb-a26e-4313-8796-c489005c901d-onExceptionTrack"
        },
        "id": "beec81bb-a26e-4313-8796-c489005c901d",
        "type": "connector",
        "name": "stream-db-connector-v3"
      },
      {
        "stepName": "agrupa resumo",
        "params": {
          "json": "{\n \"summary\": {{ message.$ }}\n}",
          "failOnError": false
        },
        "id": "1200afd4-cd17-47e4-92e8-d8b9f5e21d8d",
        "type": "connector",
        "name": "json-generator-connector"
      },
      {
        "stepName": "put summary",
        "operation": "PUT",
        "sessionType": "LOCAL",
        "fields": [
          "summary"
        ],
        "scoped": false,
        "id": "61abe3ae-76f5-4aa9-a0e0-1efac1761de6",
        "type": "session-management"
      },
      {
        "type": "session-management",
        "stepName": "get control",
        "operation": "GET",
        "sessionType": "LOCAL",
        "scoped": false,
        "fields": [
          "control"
        ],
        "id": "255bfcd8-01da-48a0-b87f-058f27ffcb29"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "jsonPath": "$.[?(@.summary.total < @.control.limit)]",
            "target": "acabou a paginação"
          }
        ],
        "otherwise": "próxima página",
        "id": "14bb99b3-a847-4fce-87fc-92b0ee4f75e3"
      }
    ],
    "beec81bb-a26e-4313-8796-c489005c901d-onProcessTrack": [
      {
        "stepName": "publica evento de processamento",
        "params": {
          "eventName": "evt-proc-handson-architecture-danilo-loose-t33",
          "body": "{{ message.$ }}",
          "showSendEventLog": false,
          "stopOnError": false
        },
        "id": "164942d0-8d6f-4336-8e44-435a785cc831",
        "type": "connector",
        "name": "event-publisher-connector"
      },
      {
        "stepName": "mensagem de sucesso",
        "params": {
          "json": "{\n \"success\": true\n}",
          "failOnError": false
        },
        "id": "b084d694-7d97-483f-a7dd-afc19ec123e6",
        "type": "connector",
        "name": "json-generator-connector"
      }
    ],
    "beec81bb-a26e-4313-8796-c489005c901d-onExceptionTrack": [
      {
        "stepName": "Log - onException Stream DB",
        "params": {
          "logLevel": "ERROR",
          "message": "onException stream DB"
        },
        "id": "3ef82a05-0abc-4eb3-b274-7db5835ab6f5",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "publica evento de erro",
        "params": {
          "eventName": "error-event-pagination",
          "body": "{{ message.$ }}",
          "showSendEventLog": false,
          "stopOnError": false
        },
        "id": "66ca7207-57c1-4570-8a46-3481abed9592",
        "type": "connector",
        "name": "event-publisher-connector"
      },
      {
        "type": "connector",
        "name": "throw-error-connector",
        "stepName": "Throw Error",
        "params": {
          "errorMessage": "Error occurred.",
          "errorCode": 500,
          "customErrorEnabled": false,
          "failOnError": true
        },
        "id": "1051c76e-ef85-46a7-a783-05f03aa12358"
      }
    ],
    "acabou a paginação": [
      {
        "stepName": "Log - acabou a paginação",
        "params": {
          "logLevel": "WARN",
          "message": "acabou a paginação"
        },
        "id": "dc5d99dd-c880-4fd5-8a0f-97113e619606",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "atualizar parâmetros da paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "UPDATE",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "document": "{\n $set:{\n \"start\": 0,\n \"end\": null,\n \"step\": \"FINISHED\",\n \"nextExecutionTimestamp\": {{ FORMATDATE(FORMATDATE(SUMDATE( NOW() , \"DAY\", 1), \"timestamp\", \"dd/MM/yyyy 01:00:00\"), \"dd/MM/yyyy HH:mm:ss\", \"timestamp\") }}\n }\n}",
          "unique": true,
          "isolated": false,
          "upsert": true,
          "failOnError": false
        },
        "id": "a3e438f1-c3cb-47fd-a16f-058c8d452b68",
        "type": "connector",
        "name": "object-store-connector"
      },
      {
        "operation": "GET",
        "scoped": false,
        "sessionType": "LOCAL",
        "stepName": "get control",
        "fields": [
          "control"
        ],
        "type": "session-management",
        "id": "d1163524-a410-4820-9649-5c43191e78cc"
      },
      {
        "stepName": "cria output",
        "params": {
          "json": "{\r\n \"message\": {{ CONCAT(\"Migration will start at \", FORMATDATE( message.control.nextExecutionTimestamp, \"timestamp\", \"dd/MM/yyyy HH:mm:ss\")) }}\r\n}\r\n",
          "failOnError": false
        },
        "id": "f236ae9e-8519-4e98-8151-0b011689e981",
        "type": "connector",
        "name": "json-generator-connector"
      }
    ],
    "próxima página": [
      {
        "stepName": "Log - próxima página",
        "params": {
          "logLevel": "INFO",
          "message": "proxima pagina"
        },
        "id": "fe6a50ad-98c9-4c95-8da0-e1a315ca0596",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "atualizar parâmetros da paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "UPDATE",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "document": "{\n $set:{\n \"start\": {{ message.control.end }},\n \"end\": {{ TOINT(SUM(message.control.end, message.control.limit)) }},\n \"step\": \"EXTRACTING_DATA\"\n }\n}",
          "unique": true,
          "isolated": false,
          "upsert": true,
          "failOnError": false
        },
        "id": "247dccab-af16-401f-bc85-385d0a0d7eee",
        "type": "connector",
        "name": "object-store-connector"
      },
      {
        "stepName": "obter parâmetros da paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "FIND",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "limit": "0",
          "skip": "0",
          "sort": "{}",
          "unique": true,
          "isolated": false,
          "upsert": false,
          "failOnError": false
        },
        "id": "3d60fe4b-8876-4b28-b22d-0970e328967a",
        "type": "connector",
        "name": "object-store-connector"
      },
      {
        "stepName": "cria output",
        "params": {
          "json": "{\n \"message\": \"The data is being migrated.\",\n \"next_execution\": {{ message.data[0] }}\n}",
          "failOnError": false
        },
        "id": "16735d3e-2e97-4478-be30-7648d0fa33d9",
        "type": "connector",
        "name": "json-generator-connector"
      }
    ],
    "FINISHED (1)": [
      {
        "stepName": "Log - FINISHED",
        "params": {
          "logLevel": "INFO",
          "message": "FINISHED"
        },
        "id": "d789cf6d-7aaf-4adb-b310-d41d1e876b85",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "jsonPath": "$.[?(@.control.nextExecutionTimestamp != null)]",
            "target": "nextExecutionTimestamp não é null"
          }
        ],
        "otherwise": "nextExecutionTimestamp é null",
        "id": "b4b32036-a35b-42d7-9aef-146865104d17"
      }
    ],
    "nextExecutionTimestamp não é null": [
      {
        "stepName": "Log - nextExecutionTimestamp não é null",
        "params": {
          "logLevel": "INFO",
          "message": "nextExecution preenchido"
        },
        "id": "422e66af-dc41-4941-b7ce-5dedbc57e9f7",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "type": "choice",
        "stepName": "Choice",
        "when": [
          {
            "jsonPath": "$.control.[?(@.startTimestamp>= @.nextExecutionTimestamp)]",
            "target": "recomeçar migração"
          }
        ],
        "otherwise": "esperar até a próxima migração",
        "id": "414b3c40-57fd-46d1-b396-09438646a403"
      }
    ],
    "recomeçar migração": [
      {
        "stepName": "Log - recomeçar migração",
        "params": {
          "logLevel": "INFO",
          "message": "recomeçar a migração"
        },
        "id": "2fcc5e50-ab4a-4003-999c-618604ead6a1",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "atualizar parâmetros da paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "UPDATE",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "document": "{\n $set:{\n \"step\": \"EXTRACTING_DATA\"\n }\n}",
          "unique": true,
          "isolated": false,
          "upsert": true,
          "failOnError": false
        },
        "id": "77a2dc52-9b57-4dad-b20e-a4ec8c8883d6",
        "type": "connector",
        "name": "object-store-connector"
      },
      {
        "stepName": "cria output",
        "params": {
          "json": "{\n \"message\": \"Migration will start at the next execution.\"\n}",
          "failOnError": false
        },
        "id": "83d038fa-ac4d-4eff-ba4c-0a870b16440b",
        "type": "connector",
        "name": "json-generator-connector"
      }
    ],
    "esperar até a próxima migração": [
      {
        "stepName": "Log - esperar até a próxima migração",
        "params": {
          "logLevel": "INFO",
          "message": "esperar"
        },
        "id": "a222d3e6-0c2e-4132-bb50-c4cc94ef9195",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "cria output",
        "params": {
          "json": "{\n \"mensagem\": {{ CONCAT(\"Migration will begin at \", FORMATDATE( message.control.nextExecutionTimestamp, \"timestamp\", \"dd/MM/yyyy HH:mm:ss\")) }}\n}",
          "failOnError": false
        },
        "id": "ff25540c-01e6-42a4-af81-d89699a7f5d2",
        "type": "connector",
        "name": "json-generator-connector"
      }
    ],
    "nextExecutionTimestamp é null": [
      {
        "stepName": "Log - nextExecutionTimestamp é null",
        "params": {
          "logLevel": "WARN",
          "message": "nextExecution nulo"
        },
        "id": "b3d89cf2-6d0c-447c-8990-fabc2a7f4ae2",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "stepName": "atualiza parâmetros de paginação",
        "accountLabel": "dgb-internal-object-store-account",
        "params": {
          "operation": "UPDATE",
          "objectStore": "pagination-OS-example",
          "objectId": "{{ CONCAT(metadata.pipeline.name, \"_v\" , metadata.pipeline.versionMajor) }}",
          "document": "{\n $set:{\n \"nextExecutionTimestamp\": {{ FORMATDATE(FORMATDATE(SUMDATE( NOW() , \"DAY\", 1), \"timestamp\", \"dd/MM/yyyy 01:00:00\"), \"dd/MM/yyyy HH:mm:ss\", \"timestamp\") }}\n }\n}",
          "unique": true,
          "isolated": false,
          "upsert": true,
          "failOnError": false
        },
        "id": "00b06e8d-f5de-47ae-87a6-ade931cac2e6",
        "type": "connector",
        "name": "object-store-connector"
      }
    ],
    "erro - step desconhecido": [
      {
        "stepName": "Log - erro step desconhecido",
        "params": {
          "logLevel": "ERROR",
          "message": "Error processing message {{ message.$.myField }}"
        },
        "id": "318cb4a9-d653-4409-ac59-aac54b00b34b",
        "type": "connector",
        "name": "log-connector"
      },
      {
        "type": "connector",
        "name": "throw-error-connector",
        "stepName": "Throw Error",
        "params": {
          "errorMessage": "Error occurred.",
          "errorCode": 500,
          "customErrorEnabled": false,
          "failOnError": true
        },
        "id": "bf4a9f9e-0d6e-4775-a886-e4b321fd846f"
      }
    ]
  }
}

Last updated

Was this helpful?