Se você está desenvolvendo APIs REST com Spring Boot, em algum momento vai precisar implementar paginação e ordenação. Seja para retornar milhares de registros com performance ou para dar flexibilidade ao frontend, esses recursos são fundamentais para qualquer aplicação moderna.
Neste artigo, vamos complementar o que foi mostrado no vídeo(https://meet.google.com/mmx-mzyp-fbg) e explicar passo a passo como montar um endpoint paginado e ordenado usando PageRequest
, Page<T>
e DTOs.
Objetivo
Criar um endpoint que permita:
- Retornar dados paginados (com base em
page
elinesPerPage
) - Ordenar os dados dinamicamente (por
orderBy
edirection
) - Retornar um
DTO
em vez da entidade para evitar vazamento de dados
Implementando no Controller
@GetMapping
public ResponseEntity<Page<CategoriaDTO>> findAllPaged(
@RequestParam(defaultValue = "0") Integer page,
@RequestParam(value = "linesPerPage", defaultValue = "12") Integer linesPerPage,
@RequestParam(value = "direction", defaultValue = "ASC") String direction,
@RequestParam(value = "orderBy", defaultValue = "nome") String orderBy
) {
PageRequest pageRequest = PageRequest.of(
page,
linesPerPage,
Direction.valueOf(direction.toUpperCase()),
orderBy
);
Page<CategoriaDTO> categorias = categoriaService.findAllPaged(pageRequest);
return ResponseEntity.ok().body(categorias);
}
O que estamos fazendo aqui?
Esses parâmetros não são obrigatórios, pois têm valores padrão definidos. Eles tornam o endpoint mais flexível e evitam que o frontend ou o Postman tenham que sempre passar todos os valores manualmente.
Entenda o significado de cada parâmetro:
page
: indica qual página você quer retornar (a contagem começa em 0).linesPerPage
: define quantos registros devem ser retornados por página.direction
: define se a ordenação será crescente (ASC
) ou decrescente (DESC
).orderBy
: campo da entidade que será usado para ordenar os resultados (ex:nome
,id
).
Com esses parâmetros, você consegue montar uma API que retorna dados paginados e ordenados com extrema facilidade.
Implementando na Service
@Transactional(readOnly = true)
public Page<CategoriaDTO> findAllPaged(PageRequest pageRequest) {
Page<Categoria> categorias = categoriaRepository.findAll(pageRequest);
return categorias.map(CategoriaDTO::new);
}
Por que @Transactional(readOnly = true)
?
- Essa anotação melhora a performance e deixa claro que esse método só faz leitura.
- Evita bloqueios desnecessários no banco de dados.
Conversão com .map(...)
- O
Page
do Spring Data tem um métodomap()
que aplica uma função de transformação para cada elemento. - Aqui, convertemos cada
Categoria
paraCategoriaDTO
usandonew CategoriaDTO(x)
.
Testando com o Postman (ou navegador)

Exemplo de requisição:
GET http://localhost:8080/categoria?page=1&linesPerPage=10&direction=DESC&orderBy=nome
O que isso faz?
- Busca a segunda página de resultados (lembrando que a contagem começa do zero)
- Retorna até 10 registros por página
- Ordena os resultados de forma descendente pelo campo
nome
Você também pode omitir os parâmetros:
GET http://localhost:8080/categoria
E a aplicação usará os valores padrão:
- page = 0
- linesPerPage = 12
- direction = ASC
- orderBy = nome
Se você tiver 14 registros no banco, por exemplo, a primeira página trará os 12 primeiros, e a segunda trará os 2 restantes.
Considerações finais
PageRequest
é a forma mais simples e poderosa de implementar paginação no Spring Boot.- O uso de
DTO
melhora a segurança e clareza da resposta. - A ordenação dinâmica permite criar um endpoint mais flexível, sem precisar hardcodar regras.
- Os parâmetros
page
,linesPerPage
,orderBy
edirection
são opcionais, com valores padrão que facilitam testes rápidos e uso em frontend.
Na próxima aula/vídeo, vamos aprender a aplicar filtros dinâmicos e fazer buscas com parâmetros no corpo ou na query da requisição. Vamos seguir juntos nessa jornada de evolução com Spring Boot! 🚀