Nova melhoria: Paginação na API e no Site 🎉
Agora tanto a API do TabNews quanto o Site possuem paginação para tudo que é relacionado a content
e que foi implementado através desse PR* com esforços meus e dos participantes que estão no repositório.
Paginação na API
A paginação foi implementada nos endpoints /api/v1/contents
e /api/v1/contents/[username]
e que agora aceitam dois novos query strings: page
e per_page
, por exemplo:
- https://www.tabnews.com.br/api/v1/contents?page=1&per_page=2
- https://www.tabnews.com.br/api/v1/contents/filipedeschamps?page=1&per_page=2
Caso você faça um request para estes endpoints sem declarar nenhum dos dois parâmetros, serão utilizados os seguintes valores padrão: page=1
e per_page=30
. Para quem implementou algum client
que utiliza a API, isto não é uma breaking change de interface
, mas de comportamento, pois antes uma request pelos conteúdos fazia devolver todos os itens.
E toda navegação pode ser automatizada pelo Header
da resposta, pois todas as informações de paginação estão sendo retornadas por lá e isso possibilita construir navegações em qualquer tipo de client
.
Então os novos cabeçalhos disponíveis são: X-Pagination-Total-Rows
e Link
.
O cabeçalho X-Pagination-Total-Rows
é simples e retorna o número total de itens no banco de dados para aquela busca. Por exemplo, se você estiver usando o fetch
para buscar esse valor, basta executar response.headers.get('X-Pagination-Total-Rows');
e isso irá retornar o valor total de linhas para aquela query. Se o banco possui 60
linhas para aquela query, aquele código ali em cima vai retornar a string '60'
.
O cabeçalho Link
segue a RFC 5988, a mesma utilizada pelo GitHub, e ela devolve as URLs absolutas para que o seu próprio código consiga sozinho navegar pela paginação, sem você precisar montar nenhuma URL manualmente, basta utilizar o que vem no cabeçalho.
Então neste cabeçalho Link
é disponibilizado todos os tipos de página que você precisa:
first
- URL absoluta da primeira páginaprev
- URL absoluta da página anteriornext
- URL absoluta da página seguintelast
- URL absoluta da última página
Esse cabeçalho pode ser adquirido da mesma forma que antes response.headers.get('Link')
e caso você não queira fazer o parsing dele na mão, há bibliotecas para isso como a parse-link-header caso esteja utilizando Node.js ou JavaScript e que irá devolver um objeto como este:
// Teste em "localhost" com 60 conteúdos e paginação default (page=1 e per_page=30)
// GET http://localhost:3000/api/v1/contents
{
first: {
page: '1',
per_page: '30',
rel: 'first',
url: 'http://localhost:3000/api/v1/contents?page=1&per_page=30',
},
next: {
page: '2',
per_page: '30',
rel: 'next',
url: 'http://localhost:3000/api/v1/contents?page=2&per_page=30',
},
last: {
page: '2',
per_page: '30',
rel: 'last',
url: 'http://localhost:3000/api/v1/contents?page=2&per_page=30',
},
}
Note que nesse exemplo acima não existe a chave prev
, pois se você estiver na página 1
, de fato não há página anterior.
Da mesma forma, a última página não retornaria next
, pois não há página seguinte. E isso é ótimo caso você queira mostrar ou não botões como "próxima página" ou "página anterior" verificando apenas a existência ou não dessa chave no cabeçalho de resposta.
Um dos casos dos nossos testes automatizados* inclusive navega automaticamente entre uma página e outra utilizando a URL disponibilizada no header Link
.
E fora isso, você também pode computar e interpolar todas as páginas intermediárias utilizando todas as informações acima.
Paginação no Site
A Home do TabNews e Página do Usuário agora contam com paginação, mas que por limitações do Next.js (na verdade, por decisão de design), não é possível usar query strings em páginas estáticas e a única forma hoje (sem utilizar um Middleware no edge), é colocar a paginação no path
mesmo.
Então na Home, as páginas ficarão assim: /pagina/1
, /pagina/2
, etc... e na página do Usuário, ficará assim: /filipedeschamps/pagina/1
, /filipedeschamps/pagina/2
.
Fora isso, uma melhora de performance foi feita: antes, toda vez que um usuário entrava na Home, ele fazia um hit extra contra a API para pegar os dados mais atualizados. Isso acontecia pois um usuário sempre poderia abrir uma página desatualizada por conta do revalidate
que utilizamos nas páginas estáticas. A necessidade desse primeiro hit foi substituído pelo response.unstable_revalidate
do Next.js e agora a cada nova publicação, esse método atualiza a primeira página da Home automaticamente. O revalidate
continua a cada 1 segundo para garantir que outras atualizações paralelas continuem fazendo a página ser atualizada, como por exemplo, um PATCH
em um content e outros lugares onde ainda não utilizamos o response.unstable_revalidate
.
Notamos que o response.unstable_revalidate
trouxe um impacto de performance (na hora de criar uma nova publicação) e vamos investigar mais a fundo esse comportamento, mas o acesso as páginas geradas estaticamente continua normal e distribuído pela CDN da Vercel.
Progresso da Milestone
Com a entrega dessa feature, 3 issues foram fechadas, o que levou a Milestone 4 para 57% concluída:
*Atenção: se você receber um 404
no link acima, você ainda não tem acesso ao repositório do TabNews. Para ser convidado, confira esse link.