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.