Ir para o conteúdo

Lidar com paginação ao ler de uma API no Jitterbit Studio

Introdução

A maioria das APIs REST limita o número de registros retornados em uma única resposta. Quando um conjunto de dados é maior que esse limite, a API divide os resultados entre várias páginas e espera que o chamador solicite cada página em sequência. Sem suporte a paginação, uma operação do Studio recupera apenas a primeira página e descarta silenciosamente o restante.

Este guia cobre a abordagem de paginação por número de página, onde cada solicitação inclui um parâmetro page que aumenta a cada chamada. Uma observação no final da Parte 2 descreve como adaptar o padrão para APIs baseadas em cursor.

Este guia pressupõe familiaridade com a configuração de conexões e atividades HTTP v2. Para uma introdução geral, consulte Chamar uma API REST usando o conector HTTP v2.

Padrão de design

O padrão usa duas operações:

  • Operação de buscar página: Lê uma página da API e escreve os registros no destino, usando o padrão de transformação:

    %%{init: {"themeVariables": {"lineColor": "#6b7280", "edgeLabelBackground": "#f5f5f5"}}}%% flowchart LR A[Atividade HTTP v2 GET] --> B[Transformação] --> C[Atividade de destino]
  • Operação de controlador: Uma etapa de script único que faz loop até que todas as páginas sejam recuperadas.

O script de controlador usa um loop While que chama RunOperation na operação de buscar página para cada página. RunOperation funciona de forma síncrona por padrão, portanto, as alterações de variável global feitas dentro da operação de buscar página (incluindo o sinal de que nenhuma página adicional permanece) ficam visíveis novamente no controlador após cada chamada.

Duas variáveis globais coordenam o loop:

  • page: o número da página atual, inicializado como 1 no controlador e incrementado após cada busca.
  • has_more: um sinalizador inicializado como true e definido como false pela transformação quando a última página é detectada.

Parte 1: Configurar a operação de buscar página

Etapa 1: Configurar a atividade HTTP v2 GET

  1. Na tela de design, arraste uma atividade GET HTTP v2 de um endpoint existente para a tela para iniciar a operação de buscar página.

  2. Clique duas vezes na atividade para abrir sua configuração.

  3. Nome: Digite um nome como Get Contacts Page.

  4. Caminho: Digite o caminho do endpoint da API, por exemplo /contacts.

  5. Parâmetros de Solicitação: Clique no ícone de adição para adicionar uma linha e digite o seguinte:

    • Nome: page
    • Valor: $page

    Isto passa a variável global page como parâmetro de query em cada solicitação. Adicione uma segunda linha com Nome per_page e um valor fixo como 100 para controlar o número de registros retornados por página.

  6. Clique em Próximo.

Etapa 2: Definir o esquema de resposta

  1. Selecione Sim, Fornecer Novo Esquema.

  2. Digite um esquema JSON que inclua o array de registros e o campo de metadados de paginação retornado pela API. O exemplo de esquema a seguir representa uma resposta que inclui um array contacts e um campo total_pages:

    {
      "type": "object",
      "properties": {
        "contacts": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "name": { "type": "string" },
              "email": { "type": "string" }
            }
          }
        },
        "total_pages": { "type": "integer" }
      }
    }
    

    Ajuste o esquema para corresponder à estrutura real de resposta da sua API.

  3. Clique em Próximo e depois em Concluído.

Parte 2: Extrair estado de paginação na transformação

A transformação mapeia os campos de origem da atividade GET para a atividade de destino e usa um script para atualizar a variável global has_more com base em se há mais páginas restantes.

  1. Abra a transformação que segue a atividade GET.

  2. Mapeie cada campo do array de origem contacts para os campos de destino correspondentes.

  3. Na transformação, adicione um script no nível raiz (fora do nó de looping) que define has_more com base no valor total_pages da resposta:

$total_pages = Source.total_pages;
If($page >= $total_pages, $has_more = false);

Isso lê o valor total_pages da resposta e define $has_more = false quando a página atual é a última.

Dica

Se a API não retornar uma contagem total de páginas, mas simplesmente retornar menos registros do que o tamanho da página quando a última página é atingida, use a contagem de registros para detectar o fim:

If(Count(Source.contacts.id) < 100, $has_more = false);

Substitua 100 pelo valor per_page configurado na atividade GET.

Paginação baseada em cursor

Algumas APIs retornam um cursor ou uma URL next_page na resposta em vez de uma contagem total de páginas. Para adaptar esse padrão para APIs baseadas em cursor, substitua page por uma variável global cursor (inicializada como ""), passe cursor como um parâmetro de requisição chamado cursor e, no mapeamento de transformação, mapeie o campo next_cursor da resposta para cursor. Defina has_more = false quando cursor estiver vazio:

$cursor = Source.next_cursor;
If($cursor == "", $has_more = false);

Remova o incremento $page++ do script do controlador descrito na Parte 3.

Parte 3: escrever o script do controlador

A operação do controlador contém um único script que inicializa o estado do loop e chama a operação de busca de página repetidamente até que todas as páginas sejam processadas.

  1. Na tela de design, crie uma nova operação contendo apenas uma etapa Script.

  2. Clique duas vezes no script para abrir o editor e digite o seguinte:

    $page = 1;
    $has_more = true;
    
    While($has_more,
        If(!RunOperation("<TAG>operation:Fetch Page</TAG>"), RaiseError(GetLastError()));
        $page++;
    );
    

    Substitua Fetch Page pelo nome exato da operação de busca de página.

  3. Salve o script.

Pontos-chave sobre este script:

  • page e has_more são variáveis globais herdadas pela operação de busca de página em cada chamada RunOperation síncrona.
  • Após cada página ser processada, o controlador incrementa page antes de iniciar a próxima iteração.
  • RaiseError(GetLastError()) interrompe o loop imediatamente e expõe a falha se a operação de busca de página retornar um erro.
  • RunOperation também está sujeito a um limite separado no nível do agente para chamadas síncronas feitas dentro de um único loop While (50 por padrão). Se a API paginasse mais de 50 páginas, este loop atingiria esse limite antes de has_more ficar false: RunOperation retorna false e RaiseError(GetLastError()) interrompe a operação com a mensagem de erro do limite em vez de concluir a sincronização. Veja a observação em RunOperation para configurar ou substituir este limite.
  • A função While impõe uma contagem máxima de iterações, que é padronizada em 50.000. Para APIs com conjuntos de dados muito grandes, defina $jitterbit.scripting.while.max_iterations para um limite apropriado antes do loop:

    $jitterbit.scripting.while.max_iterations = 2000;
    $page = 1;
    $has_more = true;
    
    While($has_more,
        If(!RunOperation("<TAG>operation:Fetch Page</TAG>"), RaiseError(GetLastError()));
        $page++;
    );
    

Verificar a integração

Implante e execute a operação do controlador. Verifique os logs da operação: a operação de busca de página aparece uma vez por página, então a contagem de entradas de log confirma quantas páginas foram recuperadas. Verifique se a contagem total de registros no destino corresponde ao conjunto de dados completo esperado da API.

Para testar a terminação antecipada antes de processar um conjunto de dados completo, defina $jitterbit.scripting.while.max_iterations = 3 no script do controlador na primeira execução. Isso limita o loop a três páginas e permite confirmar que o incremento de página, o mapeamento de esquema e a lógica has_more estão funcionando corretamente antes de remover o limite e executar o conjunto de dados completo.

Para adicionar tentativas automáticas se uma busca de página falhar, veja Tentar novamente uma operação com falha. Para orientação sobre como construir cadeias de consulta com valores de cursor ou filtro dinâmicos, veja Criar cadeias de consulta dinâmicas para chamadas de API REST.