5
respostas

Criando o controller e router

Comecei a desenvolver desde do curso, utilizando o banco de dado mysql junto com node js. Fiz a criação do arquivo router e controller para ficar organizado o escopo do projeto livros.

Queria saber se ficou certo a logica do codigo que fiz nos 2 arquivos? até a importação eas bibliotecas e o nome do arquivo js.
Ah no arquivo do controller importei a configuração iniciais do banco de dados para conseguir realizar na função uma leitura de dados sobre a tabela livros e assim conseguir retornar a respota com sucesso, caso não der certo mostra o erro no console. Segue os codigos abaixos:

import conectaNaDataBase from './config/db.js';

class LivroControlador {
    
    static async listarLivros(request, response) {
        try {
            const conexao = await conectaNaDataBase();
            const livroSQL = await conexao.query('SELECT * from livros');
            response.status(200).json(livroSQL[0]);
        } catch (erro) {
            response.json(erro);
            console.log(erro);
        }
    }
};

module.exports = LivroControlador; 
import express from 'express';
import LivroControlador from '../controllers/livroController.js'

const router = express.Router();

// Rota para listar os livros
router.get('/livros', LivroControlador.listarLivros);

export default router;

Ao fazer isso, vai deixar de existir no app.js a utilização de rota e função assincrona direto, porque vai estar utilizando o controller e a rota separadas no outro arquivo que estarão conectado para gerar ações entre eles.

Matricule-se agora e aproveite até 50% OFF

O maior desconto do ano para você evoluir com a maior escola de tecnologia

QUERO APROVEITAR
5 respostas

Oi, Rafael! Como vai?

Agradeço por compartilhar seu código com a comunidade Alura.

Sua estrutura está bem organizada com o uso de controller e router.

Para melhorar ainda mais, seria interessante padronizar a forma de exportar. Já que você usa import, mantenha também export default no lugar de module.exports. Assim, o código fica mais coerente e compatível com o uso de módulos ES. Além disso, vale ajustar o tratamento de erros para enviar uma resposta adequada ao cliente, e não apenas o log no console.

Uma dica interessante para o futuro é usar mysql2/promise com createPool para gerenciar conexões de forma mais eficiente. Veja este exemplo:


import mysql from 'mysql2/promise';
import express from 'express';

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'senha',
  database: 'biblioteca'
});

export default class LivroControlador {
  static async listarLivros(req, res) {
    try {
      const [rows] = await pool.query('SELECT * FROM livros');
      res.status(200).json(rows);
    } catch (err) {
      console.error(err);
      res.status(500).json({ mensagem: 'Erro ao listar livros' });
    }
  }
}

const router = express.Router();
router.get('/livros', LivroControlador.listarLivros);
export default router;

Esse código cria um pool de conexões e faz a leitura dos livros com pool.query.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Boa noite. Oi rafaela, estou bem.
Cheguei a ajustar a padronização da estrutura export para o código ficar mais coerente e compátivel com modulo que venha trabalhando no console. Segue o código:

class LivroControlador {

    static async listarLivros(request, response) {
        try {
            //uso do await na variável conexao está correto, desde que a função database() 
            //seja realmente assíncrona e retorne uma conexão válida com suporte a .query()
            const conexao = await database();
            const livroSQL = await conexao.query('SELECT * from livros');
            response.status(200).json(livroSQL[0]);
        } catch (erro) {
            resposta.status(500).json({ message: 'erro ao listar livro'});
        }
    };
}

A dica achei até interessante, mas tinha utilizado o metodo createConnection para criar a conexoes com o banco e depois fiz um função assincrona para testar a conexao do banco que estava usando, percebi que estava fazendo errado quando estava fazendo esta logica, segue o código:

//Importada a biblioteca mysql2
import mysql from 'mysql2/promise';

//Cria a conexão com o banco de dados
const conexaoDB =  mysql.createConnection({
    host: process.env.HOST,
    port: process.env.PORTA,
    user: process.env.USER,
    password: process.env.PASSWORD,
    database: process.env.DATABASE
});

//Realiza a conexão com o banco de dados usando um função assincrona
async function conectaNaDataBase() {
    conexaoDB.connect(
      console.log('Conectado ao banco de dados MySQL!')
  );
  return conexaoDB; 
};

export default conectaNaDataBase;

Fica acusando que o conexaoDB.connect não é um função. Da forma que fiz para criar a conexão ficou certo mas o retorno da função não, correto? To vendo que confudi a biblioteca de importacao com o metodo que usei para testar a conexão ou não...

Pensei neste connect, porque vi no site a pessoa usando para testar a conexao do banco mysql e depois imprimir uma mensagem avisando que foi conectado com sucesso o db mysql.

Oi, Rafael!

Sobre sua última dúvida: o erro ocorre porque mysql2/promise não usa connect(). Ao criar a conexão com createConnection ou createPool, ela já está pronta para uso. Basta remover o connect() e seguir o padrão abaixo:


// src/config/db.js
import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: process.env.MYSQL_HOST,
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
  database: process.env.MYSQL_DATABASE,
  waitForConnections: true,
  connectionLimit: 10
});

export default pool;

// src/controllers/livroController.js
import pool from '../config/db.js';

export default class LivroControlador {
  static async listarLivros(request, response) {
    try {
      const [rows] = await pool.query('SELECT * FROM livros');
      response.status(200).json(rows);
    } catch (erro) {
      console.error(erro);
      response.status(500).json({ mensagem: 'Erro ao listar livros' });
    }
  }
}

Resumindo:

  • Tire o connect(), pois ele não existe em mysql2/promise.
  • Use createPool() para gerenciar conexões automaticamente.
  • Padronize import e export default.

Fico à disposição. Abraços e bons estudos!

Oi rafaela.

Entendi, já fica automatico para usar a conexão direta ao usar o metodo createConnection ou createPool.
Removi o connect() e segui o padrão que voce falou:

//Importada a biblioteca mysql2
import mysql from 'mysql2/promise';

//Cria a conexão com o banco de dados
const pool =  mysql.createPool({
    host: process.env.HOST,
    port: process.env.PORTA,
    user: process.env.USER,
    password: process.env.PASSWORD,
    database: process.env.DATABASE,
    waitForConnections: true,
    connectionLimit: 10
});

export default pool;
import pool from '../config/db.js';

class LivroControlador {

    static async listarLivros(request, response) {
        try { 
            //uso o await para retornar uma conexão válida com suporte da .query()
            const livroSQL = await pool.query('SELECT * from livros');
            response.status(200).json(livroSQL[0]);
        } catch (erro) {
            resposta.status(500).json({ message: 'erro ao listar livro'});
        }
    };

Obrigado pela duvidas Rafaela. Caso surge outra duvida, não vou hesitar de consultar você.

Uma outra dúvida, no mysql tem alguma biblioteca que consigo para criar o schema do banco para definir o nome da tabelas, as colunas e o seus tipos de dados? Falo isso, porque vi que não tem uma biblioteca que cria o schema para o banco mysql. Como são banco diferentes, com certeza tem bilbiotecas que são uteis para um e outros não. Tive que criar o database, a tabela, suas colunas e seus tipos tudo manual no mysql!