Migrando a paginação antiga
Migrando sua integração de paginação por página usando parâmetro page para o cursor
Para garantir a melhor experiência e performance, estamos migrando nossa paginação de page para cursor. Essa mudança traz um ganho significativo, especialmente para grandes volumes de dados.
A paginação por cursor oferece mais estabilidade e eficiência, pois aponta para uma posição fixa na lista de resultados. Isso minimiza problemas caso os dados sejam alterados durante a sua iteração.
Incentivamos você a migrar para o novo método para aproveitar todos os benefícios de uma integração mais robusta e performática.
Esta migração não é só uma recomendação de uso
A migração para a paginação por cursor é crucial para a excelência das operações que a PipeRun oferece. Por isso, a adoção deste novo método não é apenas uma recomendação, mas sim um passo que se tornará obrigatório em breve.
Migre sua integração com ajuda de IA: paginação page → cursor
Se você usa uma ferramenta de IA (Claude, ChatGPT, Copilot, Gemini, Cursor etc.), copie o bloco abaixo, cole junto com o código da sua integração e peça a refatoração. Revise o resultado antes de aplicar em produção.
Refatore minha integração com a API do CRM PipeRun (`api.pipe.run`) para migrar da paginação antiga por número de página (parâmetro `page`) para a nova paginação por cursor (parâmetro `cursor`). Analise o código que vou fornecer, identifique **todos** os pontos que listam dados paginados da PipeRun e reescreva-os no formato novo, mantendo a linguagem e o estilo do código original.
Se o meu código for **Python**, antes de refatorar, avalie a biblioteca oficial `piperun-extractor` (https://github.com/crmpiperun/piperun-extractor). Ela já implementa a paginação por cursor, faz carga incremental por data (`after`) e exporta para JSONL/Parquet. Se ela cobrir o meu caso de uso, recomende substituí-la ao código customizado em vez de refatorar; mantenha código próprio apenas se houver requisito que a biblioteca não atende, e justifique.
## Formato antigo (a remover)
Requisição:
```http
GET /v1/deals?show=10&page=1
```
Resposta (campos de paginação):
```json
{
"success": true,
"data": [{}, {}],
"meta": {
"total": 50,
"count": 10,
"per_page": 10,
"current_page": 1,
"total_pages": 5,
"links": { "next": "https://api.pipe.run/v1/deals?show=10&page=2" }
}
}
```
A iteração incrementava `page` até atingir `total_pages` ou `data` vir vazio.
## Formato novo (a adotar)
Primeira requisição — o `cursor` vazio é proposital:
```http
GET /v1/deals?show=10&cursor=
```
Resposta (campos de paginação):
```json
{
"success": true,
"data": [{}, {}],
"meta": {
"cursor": {
"current": null,
"prev": null,
"next": "eyJpZCI7NDA2NTA3UTYsIl9wb2ludHNUb05leHRJdGVtRyI6dHJ1ZX0",
"count": null
}
}
}
```
Cada requisição seguinte repete a chamada passando em `cursor` o valor exato de `meta.cursor.next` da resposta anterior. A iteração termina quando `meta.cursor.next` vier `null`/vazio ou `data` vier vazio.
Pseudocódigo de referência (adapte à linguagem do meu código):
```python
cursor = "" # primeira chamada com cursor vazio
while True:
resp = api.get(f"/v1/deals?show=10&cursor={cursor}")
processar(resp["data"])
cursor = resp["meta"]["cursor"]["next"]
if not cursor or not resp["data"]:
break
```
## Regras obrigatórias
1. **As requisições de paginação DEVEM ser sequenciais.** Se o código atual busca páginas em paralelo — threads, workers, pool de conexões, `Promise.all`, `asyncio.gather`, goroutines, jobs em fila disparados por número de página, ou qualquer padrão do tipo "descobre `total_pages` e dispara N requisições" — remova esse paralelismo do loop de paginação. No formato novo, cada requisição depende do cursor retornado pela anterior; não existe como calcular cursors antecipadamente. Isso é uma decisão de arquitetura da PipeRun, não uma limitação a ser contornada. Paralelismo em outras partes do código (ex.: processamento dos dados após a busca) pode ser mantido.
2. Trate o cursor como uma string opaca: não decodifique, não modifique e não construa cursors manualmente. Apenas repasse o valor recebido em `meta.cursor.next`.
3. Remova toda dependência de `meta.total`, `meta.total_pages`, `meta.current_page`, `meta.per_page` e `meta.links` — esses campos não existem na resposta nova. Se houver barra de progresso ou log do tipo "página X de Y", substitua por contagem acumulada de registros processados.
4. Não altere o processamento dos dados (`data`), filtros de negócio, autenticação, retries ou tratamento de erros existentes. A mudança é apenas no mecanismo de paginação.
5. Mantenha o parâmetro `show` (tamanho da página). Para compensar a perda do paralelismo, considere aumentá-lo até o máximo permitido pela documentação da PipeRun, reduzindo o número total de requisições.
6. Evite ordenações avançadas/customizadas nas consultas paginadas por cursor. Se o código usa parâmetros de ordenação, sinalize isso na entrega.
## Casos que você deve sinalizar, não resolver silenciosamente
- Código que pula direto para uma página específica (`page=N`): não existe equivalente no cursor, que só avança sequencialmente.
- Checkpoints que persistem o número da página para retomar uma extração interrompida: o número de página não tem significado no formato novo.
- Lógica que precisa saber o total de registros ou de páginas antes de iterar.
Para cada caso encontrado, mostre o trecho de código, explique por que ele quebra e proponha uma alternativa (ex.: reiniciar a extração com filtros incrementais por data em vez de retomar por página).
## Entrega esperada
1. O código refatorado completo de todos os trechos alterados.
2. Um resumo das mudanças: arquivo/função e o que mudou em cada um.
3. A lista de pontos de atenção sinalizados acima, se existirem.
1. Paginação Antiga (page)
page)Neste modelo, a navegação entre as páginas era feita de forma sequencial, utilizando o parâmetro page. Você informava o número da página que desejava acessar (page=1, page=2, etc.) para buscar o próximo conjunto de dados. Então você tinha uma requisição assim:
GET /v1/deals?show=10&page=1
E recebia esta resposta:
{
"success": true,
"message": "OK",
"data": [{...},{...}],
"meta": {
"total": 50,
"count": 10,
"per_page": 10,
"current_page": 1,
"total_pages": 5,
"links": {
"next": "https://api.pipe.run/v1/deals?show=1&page=2"
}
}
}
Para navegar em todas as paginas você iria iterar pagina a pagina, incrementando o número da pagina até atingir o limite de paginas ou não ter mais dados para serem recuperados. Exemplo de pseudo código em Python:
pagina = 1
while True:
response = api.get(f"/deals?show=10&page={pagina}")
// processamento dos dados
if pagina >= response["meta"]["total_pages"] or not response["data"]:
break
pagina += 1
2. Paginação Nova (cursor)
cursor)A paginação por cursor oferece um método mais robusto e eficiente, ideal para lidar com grandes conjuntos de dados. Em vez de usar um número de página, você usa o valor de cursor.next retornado na resposta da API para buscar a próxima página. Esse cursor atua como um "marcador" que aponta para o último item do conjunto de dados anterior, garantindo uma busca contínua e precisa, mesmo que os dados sejam alterados durante a sua navegação. Então, para este novo formato você terá uma requisição assim:
GET /v1/deals?show=10&cursor=
Note que o conteúdo da primeira requisição é uma string vazia, e isto é proposital.
Obtendo uma resposta como a descrita abaixo:
{
"success": true,
"message": "OK",
"data": [{...},{...}],
"meta": {
"cursor": {
"current": null,
"prev": null,
"next": "eyJpZCI7NDA2NTA3UTYsIl9wb2ludHNUb05leHRJdGVtRyI6dHJ1ZX0",
"count": null
}
}
}
Para navegar em todas as paginas você irá iterar pagina a pagina, usando a hash cursor.next da requisição anterior, até ela ser null ou não ter mais dados para serem recuperados. Neste exemplo, a segunda requisição seria assim:
GET /v1/deals?show=10&cursor=eyJpZCI7NDA2NTA3UTYsIl9wb2ludHNUb05leHRJdGVtRyI6dHJ1ZX0
Exemplo de pseudo código em Python:
cursor = "" # começa como string vazia
while True:
response = api.get(f"/deals?show=10&cursor={cursor}")
// processamento dos dados
cursor = response["meta"]["cursor"]["next"]
if not cursor or not response["data"]:
break
3. O que muda em relação ao sistema antigo?
Diferenças Práticas
| Antigo | Novo |
|---|---|
Parâmetro page=N | Parâmetro cursor=valor |
| Pode ir direto à página N | Só avança para próxima "página" conhecida |
| Possível saber total de páginas/itens | Não é possivel saber o total de páginas de imediato |
| Gera problemas se os dados mudam no meio do processo | Cursor aponta diretamente para o ponto certo, reduz esses problemas |
| Muito lento | Muito rápido |
| Ordenações avançadas são possíveis mas não recomendadas | Ordenações avançadas podem deduplicar dados com itens semelhantes |
Por quê mudar?
- Melhor para grandes volumese menos erros se os dados mudam enquanto você percorre
- Mais escalável O cursor aponta para um ponto fixo do resultado, e não depende de contagens que podem variar enquanto a lista muda.
Updated 21 days ago
