[ Conteúdo ] Apresentando Pagination API
Introdução:
Esses dias eu me deparei com pagination API
, que é na verdade uma técnica utilizada principalmente em chamadas de API, para limitar a quantidade de dados na respostas retornanda, ajudando na otimização.
Neste artigo, eu busco aprensentar o pagination
de maneira geral, e algum futuro artigo, me aprofundar mais nele com boas práticas, Tudo que precisa saber, dentre outros.
Descrição:
Comecei este artigo afirmando que pagination
é uma API, mas na verdade, é uma técnica utilizada para melhorar a performance dos seus requests. Alguns artigos se referem como API, outros se referem como uma técnica... Não achei um consenso, então irei me referer como uma técnica ao longo do artigo.
Vale lembrar que pagination
não se limita apenas a API's, também é aplicada em outras situações, mas estarei dando um foco maior em chamadas de api
.
Papel:
O papel do pagination
é melhorar a performance dos seus requests. Como ele faz isso? Supondo que temos uma lista com 300 usuários registros do banco de dados, e solicitamos esses dados, seriam 300 usuários retornando de uma só vez. Consegue imaginar o quanto de banda larga
, processamento
, memória
e demora para o usuário conseguir realizar uma ação levaria? Pois é. Agora imagine uma lista mais realista no mundo de hoje, com: 10 milhões de usuários ou até mais...? Não seria nada rápido isso.
O que o pagination
faz para resolver isso? Bom, como dito acima, pagination
é uma técnica utilizada para aprimorar a perfomance de seus requests, então quando utilizamos o pagination
, quebramos essa coleção de dados em pequenos pedaços (chunks
) e ao invés de retornar todos os dados de uma vez, retornamos apenas uma parcela deles.
Muito legal, não? Agora como eu faço isso? Preciso instalar algo? A resposta é não, não precisa instalar nada via npm
. Quando uma api
é construída, ela já tem um "suporte" para receber parametros extras, parametros esses que são o pagination
.
Exemplo:
'use client'
import useSWR from "swr";
import { useState } from "react";
import Image from "next/image";
export default function Home() {
interface Json {
"albumId": number,
"id": number,
"title": string,
"url": string,
"thumbnailUrl": string,
}
const [ count, setCount ] = useState<number>(1);
const fetcher = (url:string) => fetch(url).then(response => response.json());
const { data, error } = useSWR<Json[]>(`https://jsonplaceholder.typicode.com/photos?_page=${count}&_limit=10`, fetcher);
if(error) {
return;
}
if(!data) {
return;
}
return (
<div className="container">
{data.map((item) => (
<div key={item.id}>
<Image src={item.url} alt="testing" height={400} width={400} />
</div>
))}
<button onClick={() => setCount(count - 1)}>
previos
</button>
<button onClick={() => setCount(count + 1)}>
next
</button>
</div>
)
}
Peguei um teste meu que eu fiz a um tempinho para testar a biblioteca swr
do React junto com o next.js
. VALE LEMBRAR QUE NÃO PRECISA INSTALAR NEXT.JS
OU REACT
E MUITO MENOS O SWR
. Um simples fetch
com javascript
puro é o suficiente. Apenas peguei esse exemplo que eu já tinha prontinho.
Não funciona apenas com JavaScript, funciona com outras linguagens também, mas a forma que isso é feito, pode variar, como no PHP por exemplo.
Vamos analisar aqui, onde está o pagination
? Ele se encontra aqui: https://jsonplaceholder.typicode.com/photos?_page=${count}&_limit=10
Aqui estou chamando a jsonplaceholder
api para exemplificar, você pode encontra-la neste link aqui: jsonplaceholder.
Continuando, chamando a api
no endpoint
: photos
, que me retorna muitos dados, cerca de 5000 objetos. Muita coisa, não? o pagination
está após o photos
, aqui:?_page=${count}&_limit=10
como dito acima, mais uma vez repito, pagination
é uma técnica, e existe várias formas de aplica-la. Aqui estamos usando um método muito comum, o page-based pagination
, onde organizamos por página os dados. Observe o page=${count}
, isso é nossa página atual, que pode ser um valor númerico. O limit
determina o limite de dados retornandos por página.
Então fazendo um resumão aqui: Faço um request a um endpoint
com 5000 objetos, e depois, ao aplicar a técnica do pagination
, esses dados são quebrados em vários pedaços, e a forma que esses pedaços são organizados, foi específicado por page=${count}
, onde esse page
, é como um container, que vai conter uma certa quantidade desses pedaços específicados pelo o limit
.
Então no caso acima, estou dizendo que: quero 10 elementos dos 5000 disponíveis, por página. Então cada page
vai conter 10
elementos. Se eu clicar nos botões que possuem as funções de aumentar ou diminuir o valor do page
, os valores retornados mudarão.
No page=1
eu tenho elementos do índice 0 até o 9, esses elementos serão mostrados caso o page
seja 1
. Se eu aumentar esse valor para 2, page=2
, os dados retornados serão do índice 10 até o 19. E assim vai.
Possíveis dúvidas:
preciso instalar algo?
- Não, não precisa instalar nada, apenas procurar como implementar isso em sua linguagem. A forma que eu utilizei, se aplica no JavaScript. Em sua linguagem, pode ser de uma maneira diferente.page e limit podem ser qualquer valor númerico
: A resposta é sim, mas tenha atenção. Supondo que você coloque um limite muito acima, pode causar danos a perfomance, dentre outras coisas. Além disso, se especificar um valor maior que quantidade de dados, pode retornar umRange Error
.Essa é a única forma de aplicar essa técnica?
- Não, existe mais formas com parâmetros diferentes, até paragraphQL
.
Aplicação que utilizam:
Bom, uma visão geral já foi dada, então agora vamos conversar um pouco sobre outras formas de utilizar pagination
, e mencionar quem utiliza essa técnica.
Facebook
, twitter
, instagram
e várias outras redes sociais, até mesmo lojas como playstore
e steam
, utilizam essa técnica.
Já devem imaginar o motivo, mas explicando brevemente: Imagina a loucura que seria o Twitter
enviar todos os posts existentes para os usuários? Quantos meses levaria para carregar tudo? Bom, brincadeiras a parte, levaria bastante tempo.
Já reparou que conforme você desce a timeline
, novos posts são carregados, e as vezes da para notar um breve carregamento? Pois estão este é o pagination em conjunto com outras técnica e tecnologias. Essas Aplicação limitam a quantidade de posts carregados para o usuário quando abre o app. Conforme for descendo, incremente o page
com um limit
especificado e uma nova leva de posts são carregadas.
Algumas formas de aplicar o paginations:
Citarei algumas formas (não todas) de implementar o pagination
para determinadas situações.
offset-based pagination:
Semelhante ao page
, mas ideal para lidar com intervalos de dados específicos em um banco de dados por exemplo.
GET /api/posts?offset=0&limit=10
Aqui o offset
indica onde o ínicio do intervalo e o limit
o fim dele. Então considere o seguinte exemplo:
const example = [
const example = [
{ property: 1 },
{ property: 2 },
{ property: 3 },
{ property: 4 },
{ property: 5 },
{ property: 6 },
{ property: 7 },
{ property: 8 },
{ property: 9 },
{ property: 10 },
{ property: 11 },
];
]
Supondo que estamos fazendo um request que retorne esse objeto desta forma:
GET /api/posts?offset=3&limit=5
Objeto retornado:
[
{ property: 4 },
{ property: 5 },
{ property: 6 },
{ property: 7 },
{ property: 8 },
]
conforme específicado, o offset=3
basicamente indica que devemos pular os 3 primeiros elementos e o limit
indica que o máximo de elementos a serem retornados devem ser 5
.
Cursor-based pagination:
Diferente da técnica acima, aqui trabalhamos com identificadores únicos, ou tokens. Este método geralmente é mais utilizado quando utilizando graphQL
, pois se eu não me engano, grapQL
é baseado em cursor
também.
Não vou prover exemplos e nada muito detalhado, pois eu não sei nada sobre graphQL
, então não me sinto no direito de "ensinar" algo que nem sequer sei a base...
A ideia é apresentar a alternativa para os dev que utilizam graphQL
. Mais detalhes eu ficarei devendo.
Time-based pagination:
A paginação baseada em tempo (time-based pagination) é uma técnica de paginação que utiliza carimbos de data/hora (timestamps) para ordenar e recuperar dados em uma sequência temporal.
Esses tipos de dados, que são organizados por data, geramente são encontrado em Eventos, Bancos, dentre outros. Nesse contexto, essa abordagem se sobressai:
GET /api/events?start_time=2023-01-01T00:00:00Z&end_time=2023-01-31T23:59:59Z
Conclusão:
Não vai falar sobre o page-based pagination
? Na visão geral, eu explique tudo que deveria sobre ele no momento, então eu estaria apenas repetindo tudo que falei anteriormente. Ainda existem outras abordagens muito interessantes sobre pagination
. Espero que tenham gostado!