Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Funcionalidade de Paginação na API

Achei que seria interessante compartilhar, implementei a funcionalidade de paginação para pessoas, tanto ativas quanto ativas e inativas, adaptando o PessoaController.js e PessoaServices.js para isso. E também implementei a paginação para todos os cursos, ficou bem organizado.

Ao fazer o GET em http://localhost:3000/pessoas/todos ou http://localhost:3000/pessoas/todos?page=2 , retornara : Os objetos de cada pessoa, pagina atual, total de paginas, total pessoas "ativas ou ativas e inativas";

{
   "pessoas": [
        {
             //os objetos contendo as pessoas
        },
        {
             //os objetos contendo as pessoas
        },
   ],
    "paginaAtual": 1,
    "totalPaginas": 5,
    "totalPessoas": 10
}

Implementação em PessoaController.js :

     // Método para retornar todas as pessoas ativas com paginação
      async pegaPessoasAtivas(req, res) {
        const page = Math.max(parseInt(req.query.page) || 1, 1);   // Define a página atual, garantindo que seja pelo menos 1
        const limit = Math.max(parseInt(req.query.limit) || 2, 1);   // Define o limite de resultados por página, garantindo que seja pelo menos 1

        try {
            // Chama o serviço para obter as pessoas ativas com a paginação definida
            const { pessoas, totalPaginas, totalPessoas } = await pessoaServices.pegaPessoasAtivasPaginado(page, limit);
            // Retorna a resposta com os dados das pessoas
            res.status(200).json({ pessoas, paginaAtual: page, totalPaginas, totalPessoas });
        } catch (erro) {
            res.status(erro.message === 'Página não encontrada' ? 404 : 500).json({ erro: erro.message });
        }
      }

      // Método para retornar todas as pessoas (ativas e inativas) com paginação
      async pegaTodasAsPessoas(req, res) {
        const page = Math.max(parseInt(req.query.page) || 1, 1);  // Define a página atual, garantindo que seja pelo menos 1
        const limit = Math.max(parseInt(req.query.limit) || 2, 1);  // Define o limite de resultados por página, garantindo que seja pelo menos 1

        try {
            // Chama o serviço para obter todas as pessoas com a paginação definida
            const { pessoas, totalPaginas, totalPessoas } = await pessoaServices.pegaTodasAsPessoasPaginado(page, limit);
            // Retorna a resposta com os dados das pessoas
            res.status(200).json({ pessoas, paginaAtual: page, totalPaginas, totalPessoas });
        } catch (erro) {
            res.status(erro.message === 'Página não encontrada' ? 404 : 500).json({ erro: erro.message });
        }
      }

Implementação em PessoaService.js :


    // Busca pessoas ativas com paginação
    async pegaPessoasAtivasPaginado(page, limit) {
        
        const offset = (page - 1) * limit; // Calcula o deslocamento (offset) com base na página atual e no limite de resultados por página

        // Realiza a busca no banco de dados, contando e buscando as pessoas ativas
        const { count, rows } = await this.model.findAndCountAll({
            where: { ativo: true }, // Filtra para incluir apenas pessoas ativas
            limit, // Limita o número de resultados retornados
            offset, // Aplica o deslocamento para a paginação
            order: [['nome', 'ASC']], // Ordena os resultados pelo nome em ordem ascendente
        });

        const totalPaginas = Math.ceil(count / limit); // Calcula o total de páginas com base na contagem total de pessoas ativas e o limite

        if (page > totalPaginas) throw new Error('Página não encontrada'); // Verifica se a página solicitada existe, lançando um erro se for maior que o total de páginas

        return { pessoas: rows, totalPaginas, totalPessoas: count }; // Retorna um objeto contendo as pessoas encontradas, o total de páginas e o total de pessoas
    }

    // Busca todas as pessoas (ativas e inativas) com paginação
    async pegaTodasAsPessoasPaginado(page, limit) {

        const offset = (page - 1) * limit;

        // Realiza a busca no banco de dados, contando e buscando todas as pessoas
        const { count, rows } = await this.model.findAndCountAll({
            limit, 
            offset, 
            order: [['nome', 'ASC']], 
        });

        const totalPaginas = Math.ceil(count / limit);

        if (page > totalPaginas) throw new Error('Página não encontrada');

        return { pessoas: rows, totalPaginas, totalPessoas: count };
    }
3 respostas

A lógica segue a mesma pra a implementação em cursos, buscando GET em http://localhost:3000/cursos ou http://localhost:3000/cursos?page=2 .

Arquivo CursoController.js :

    // Método para buscar todos os cursos com paginação
    async pegaTodos(req, res) {
        const page = Math.max(parseInt(req.query.page) || 1, 1); // Define a página mínima como 1
        const limit = Math.max(parseInt(req.query.limit) || 2, 1); // Define o limite mínimo como 1

        try {
            const { cursos, totalPaginas, totalCursos } = await cursoServices.pegaTodosPaginado(page, limit); // Chama o novo método de serviços
            return res.status(200).json({ cursos, paginaAtual: page, totalPaginas, totalCursos }); // Retorna os cursos encontrados com dados de paginação
        } catch (error) {
            return res.status(500).json({ mensagem: 'Erro ao buscar cursos', erro: error.message });
        }
    }

Arquivo CursoServices.js :

   // Método para buscar todos os cursos com paginação
    async pegaTodosPaginado(page, limit) {
        const offset = (page - 1) * limit; // Calcula o offset para a consulta
        const { count, rows } = await this.model.findAndCountAll({
            limit, // Limite de cursos por página
            offset, // Offset para pular os cursos já contados
            order: [['titulo', 'ASC']], // Ordena os resultados pelo nome
        });
        const totalPaginas = Math.ceil(count / limit); // Calcula o total de páginas

        if (page > totalPaginas && totalPaginas > 0) throw new Error('Página não encontrada');

        return { cursos: rows, totalPaginas, totalCursos: count }; // Retorna os cursos, total de páginas e total de cursos
    }
solução!

Busquei deixar a API com mais recursos e bem estruturada, fazendo além, praticando várias formas e implementações. Estou aberto a sugestões. Grato!

Oi, José. Tudo bem?

Obrigada por compartilhar sua implementação.

Gostei muito da forma como você organizou a funcionalidade de paginação, tanto para as pessoas quanto para os cursos. É uma ótima prática para melhorar a usabilidade da API, permitindo que os usuários acessem os dados de maneira mais eficiente.

Conte com o apoio do Fórum na sua jornada. Abraços e bons estudos!