Gerador de resposta paginada JSON
Gera JSON com estrutura de paginação fake (page, pageSize, total, items) para mockar API REST.
—
JSON paginado mock: design de API do offset/limit ao cursor
Paginação é o problema ergonômico mais comum em design de APIs REST e GraphQL, e também um dos mais fáceis de errar. Um gerador de JSON paginado mock permite que times de front-end, devs mobile e autores de SDK construam telas, feeds com scroll infinito e tabelas antes do backend estar pronto, com envelopes de resposta que casam com o contrato de produção. Também serve como artefato didático: uma única ferramenta que emite variantes offset/limit, cursor, keyset e timestamp torna os trade-offs concretos e visíveis lado a lado.
Os quatro padrões canônicos são fáceis de reconhecer. Offset/limit usa ?page=2&limit=20 ou ?offset=20&limit=20; simples, permite pular para qualquer página, mas instável quando linhas são inseridas entre requisições e lento em tabelas grandes porque o banco ainda precisa contar e descartar as primeiras OFFSET linhas. Cursor-based usa um token opaco como ?cursor=eyJpZCI6MTAwfQ==; estável diante de inserções, rápido mesmo em bilhões de linhas, mas você não consegue saltar para a "página 50". Keyset (também chamado seek) expõe a chave de ordenação direto — ?after_id=100&limit=20 — e é o que a maioria dos cursores decodifica internamente. Timestamp-based, ?since=2024-01-01T00:00:00Z, é o ajuste natural para feeds de atividade e webhooks.
Envelopes de resposta e padrões de mercado
Uma resposta paginada quase sempre vem envolta em um envelope com duas partes: um array data com os itens e um objeto meta descrevendo a página. Campos comuns são current_page, per_page, total, total_pages, next_url e prev_url. A especificação JSON:API padroniza isso com um objeto links contendo URLs self, first, last, prev e next — um design HATEOAS em que o cliente segue links em vez de montá-los. GraphQL Relay usa connection + edges + pageInfo com endCursor e hasNextPage; Stripe retorna has_more e um auto_paging_iter() no SDK; GitHub coloca os dados de paginação no header HTTP Link em vez do corpo.
{
"data": [{ "id": 21, "name": "Item 21" }],
"meta": {
"current_page": 2,
"per_page": 20,
"total": 137,
"total_pages": 7
},
"links": {
"first": "/items?page=1&limit=20",
"prev": "/items?page=1&limit=20",
"next": "/items?page=3&limit=20",
"last": "/items?page=7&limit=20"
}
}
Paginação por cursor em detalhe
Cursores opacos costumam ser JSON em base64 contendo a chave de ordenação e o id do último item retornado, para o servidor disparar uma query WHERE (sort_key, id) > (last_sort, last_id) que atinge um índice. A opacidade importa: se os clientes aprenderem o formato, vão adulterá-lo, e mudar o schema depois quebra todo cursor cacheado por aí. Sempre inclua um byte de versão. Cursores são o default certo para feeds infinitos, logs de atividade, transações e qualquer endpoint apoiado em uma tabela que cresce continuamente; offset/limit serve para tabelas administrativas pequenas e resultados de busca em que "página 12" tem significado.
Tamanhos de página, limites e edge cases
Defaults sensatos: tamanho de página padrão 25, máximo 100, rejeite qualquer coisa maior com HTTP 400. Sempre documente o teto. Teste os edge cases que seu front vai bater: resultado vazio, resultado com exatamente limit itens (off-by-one na lógica de "tem próxima página?"), última página, requisição além da última página (retornar data vazia, não 404) e inserções concorrentes (cursor permanece estável, offset desloca). Um gerador mock que deixa você configurar total, per_page e current_page independentemente é a forma mais rápida de cobrir os quatro em testes de componente.
Perguntas frequentes
Cursor ou offset? Cursor para feeds infinitos, tabelas grandes, dados append-only e qualquer caso sensível a performance. Offset para listas administrativas pequenas, resultados de busca e qualquer cenário em que o usuário se beneficia de pular para uma página específica.
Que tamanho de página usar? Padrão 25, permita de 1 a 100, rejeite o resto. Cliente mobile costuma querer 20; exportações de dados querem 100.
Qual envelope é o padrão? Não existe um vencedor único. JSON:API é o mais prescritivo; o padrão estilo Stripe (data + has_more) é o mais copiado por APIs SaaS; o Link header do GitHub é o mais limpo mas o menos descobrível para quem consome via SDK.
Preciso retornar o total? Nem sempre. Devolver total exige uma segunda query (SELECT COUNT(*)) que pode dominar o tempo de resposta. Para feeds infinitos, has_more basta. Para tabelas paginadas que mostram "1-20 de 137", a contagem é inevitável.
Ferramentas Relacionadas
Gerador de Manuscrito
Converte texto digitado em uma imagem com aparência de letra manuscrita. Útil para tornar trabalhos digitais mais pessoais.
Gerador de Currículo
Preenche um currículo simples (CV) imprimível em A4 a partir de formulário com dados pessoais, formação e experiência.
Gerador de Favicon
Gera favicon a partir de texto/emoji em todos os tamanhos comuns (16, 32, 48, 64, 192, 512). Download como PNG.