Crear una aplicación CRUD con Node.js y MySQL

Introducción

Node.js es una plataforma de código abierto para crear aplicaciones de red rápidas y escalables. MySQL es un sistema de administración de bases de datos relacionales (RDBMS) confiable y es una buena opción para crear aplicaciones CRUD (crear, leer, actualizar y eliminar) con Node.js.

Una aplicación CRUD realiza las siguientes operaciones:

  • Create : agrega datos a una base de datos MySQL usando SQL INSERT dominio.
  • Read : consulta datos de una base de datos usando el SQL SELECT dominio.
  • Update : modifica los registros de datos utilizando el SQL UPDATE dominio.
  • Delete : elimina registros de una base de datos usando el SQL DELETE dominio.

Muchas aplicaciones basadas en datos se ejecutan sobre el patrón de programación CRUD, incluidos blogs, portales de empresas, software de comercio electrónico, aplicaciones de planificación de recursos empresariales y más. Esta guía implementa una aplicación CRUD con Node.js y MySQL en el servidor Ubuntu 20.04.

requisitos previos

Antes de que empieces:

  • Implemente un servidor Ubuntu.
  • Instale y asegure un servidor MySQL.
  • Configure un entorno de programación Node.js. Puede omitir el paso 2 (Instalar Express.js) porque no necesita la dependencia de Express.js para probar esta guía.

1. Configure una base de datos y una cuenta de usuario

En esta guía, su aplicación de muestra almacena datos de forma permanente en una base de datos MySQL. Siga los pasos a continuación para inicializar la base de datos y crear una cuenta de usuario:

  1. Inicie sesión en el servidor MySQL como root .

                              
                                $ sudo mysql -u root -p
    
                              
                            
  2. Enter su contraseña y presione ENTER para continuar. Luego, emita los siguientes comandos SQL para crear una muestra my_shop base de datos y un my_shop_user cuenta. Reemplazar EXAMPLE_PASSWORD con una contraseña segura para proteger la cuenta MySQL contra ataques de fuerza bruta.

                              
                                mysql> CREATE DATABASE my_shop;
           CREATE USER 'my_shop_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
           GRANT ALL PRIVILEGES ON my_shop.* TO 'my_shop_user'@'localhost';           
           FLUSH PRIVILEGES;
    
                              
                            

    Producción.

                              
                                ...
    Query OK, 0 rows affected (0.01 sec)
    
                              
                            
  3. Cambiar a lo nuevo my_shop base de datos.

                              
                                mysql> USE my_shop;
    
                              
                            

    Producción.

                              
                                Database changed
    
                              
                            
  4. Crear un products mesa. Esta tabla almacena información de productos que incluye: el único product_id , product_name y retail_price . Emitir el AUTO_INCREMENT palabra clave para permitir que MySQL incremente automáticamente el product_id columna cuando inserta nuevos registros en la products mesa.

                              
                                mysql> CREATE TABLE products (
               product_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               product_name VARCHAR(50),
               retail_price  DOUBLE
           ) ENGINE = InnoDB;
    
                              
                            

    Producción.

                              
                                Query OK, 0 rows affected (0.01 sec)
    
                              
                            
  5. Inserte registros de muestra en el products mesa.

                              
                                mysql> INSERT INTO products (product_name, retail_price) values ('LEATHER BELT', 18.45);
           INSERT INTO products (product_name, retail_price) values ('BLUETOOTH SPEAKER', 75.95);
           INSERT INTO products (product_name, retail_price) values ('RECHARGEABLE TORCH', 35.85);
    
                              
                            

    Producción.

                              
                                ...
    Query OK, 1 row affected (0.02 sec)
    
                              
                            
  6. consulta el products tabla para asegurarse de que los datos están en su lugar.

                              
                                mysql> SELECT
               product_id ,
               product_name,
               retail_price
           FROM products;
    
                              
                            

    Producción.

                              
                                +------------+--------------------+--------------+
    | product_id | product_name       | retail_price |
    +------------+--------------------+--------------+
    |          1 | LEATHER BELT       |        18.45 |
    |          2 | BLUETOOTH SPEAKER  |        75.95 |
    |          3 | RECHARGEABLE TORCH |        35.85 |
    +------------+--------------------+--------------+
    3 rows in set (0.00 sec)
    
                              
                            
  7. Cierre sesión en el servidor MySQL.

                              
                                mysql> QUIT;
    
                              
                            

    Producción.

                              
                                Bye
    
                              
                            

2. Crea un database_gateway Clase

Cuando se trabaja en un proyecto de Node.js, lo convencional es separar la aplicación en módulos manejables distribuidos en diferentes archivos. Este enfoque le permite depurar la aplicación rápidamente y facilita el soporte. Este paso se enfoca en crear una clase de base de datos central que puede reutilizar en todo el proyecto para acceder a su base de datos.

  1. Comience por crear un nuevo project directorio de la aplicación.

                              
                                $ mkdir project
    
                              
                            
  2. Cambiar a lo nuevo project directorio.

                              
                                $ cd project
    
                              
                            
  3. abrir un nuevo database_gateway.js archivo en un editor de texto.

                              
                                $ nano db_gateway.js
    
                              
                            
  4. Agregue la siguiente información a la database_gateway.js expediente. Recuerda reemplazar EXAMPLE_PASSWORD con la contraseña MySQL correcta para el my_shop_user cuenta.

                              
                                class db_gateway { 
    
        constructor() {
    
        }
    
        getDb() { 
    
            const mysql = require('mysql');  
    
            const db_con = mysql.createConnection({
                host: "localhost",
                user: "my_shop_user",
                password: "EXAMPLE_PASSWORD",
                database: "my_shop"
             }); 
    
            db_con.connect(function(err) {
                if (err) {               
                    console.log(err.message);             
                }                    
            });
    
            return db_con;
        } 
    
        execute(sql, params, callBack) {
    
           var db_con = this.getDb();        
    
           db_con.query(sql, params, function (err, result) {
               if (err) {
                   callBack(err, null);                   
               } else {
                   callBack(null, "Success");          
               }         
          }); 
    
        }      
    
        query(sql, params, callBack) {
    
           var db_con = this.getDb();        
    
           db_con.query(sql, params, function (err, result) {
               if (err) {
                   callBack(err, null);                   
               } else {
                   callBack(null, result);          
               }         
          }); 
    
        }      
    }
    
    module.exports = db_gateway;
    
                              
                            
  5. Guardar y close la db_gateway.js expediente.

los db_gateway.js archivo explicado:

  • El soltero db_gateway {} La clase envuelve todas las funciones de la base de datos que necesita para conectarse a la base de datos y realizar operaciones CRUD.

                              
                                class db_gateway { 
        ....
    }
    
                              
                            
  • los constructor() {} El método está vacío porque no está pasando ni inicializando ninguna variable predeterminada para esta clase.

  • los db_gateway {} La clase tiene tres métodos principales (funciones) como se explica a continuación:

    • getDb() este método se conecta a la base de datos MySQL y devuelve una conexión reutilizable ( return db_con; ) implementado por el execute() y query() métodos.

    • execute() : este método realiza el SQL INSERT , UPDATE y DELETE ordena y devuelve un Success mensaje en un callBack() función.

    • query() : este método realiza el SQL SELECT comando y devuelve una matriz asociativa que contiene datos de la products mesa.

  • Mapear las funciones de la base de datos en una clase separada le permite usar el siguiente código clásico para llamar a los métodos más adelante en esta guía:

                              
                                var db_gateway = require('./db_gateway.js');
    var dg = new db_gateway();
    
    dg.execute(sql, params, callBack);  
    dg.query(sql, params, callBack);
    
                              
                            
  • Como habrás notado, Node.js usa muchas devoluciones de llamada. Una devolución de llamada es una función que se ejecuta cuando se completa una tarea. Este modelo de devolución de llamada permite que Node.js admita una alta simultaneidad porque evita que las funciones se bloqueen entre sí.

  • los module.exports = db_gateway; línea al final le permite aprovechar la db_gateway clase en otros archivos usando el require('./db_gateway.js'); declaración.

los db_gateway la clase ya está lista. Esta aplicación de muestra luego implementa el db_gateway clase en diferentes archivos para realizar operaciones de base de datos.

3. Crea un products Clase

La cantidad de recursos o puntos finales en una aplicación CRUD puede oscilar entre uno y varios cientos. Ese número depende de la complejidad de la aplicación. Por ejemplo, los siguientes son algunos recursos y puntos finales HTTP para una aplicación de comercio electrónico típica:

                      
                        Resource    Endpoint
----------------------

products    /products

categories  /categories

customers   /customers

orders      /orders

payments    /payments

...

                      
                    

Al diseñar su aplicación, debe crear clases separadas para todos los recursos para crear un código limpio que pueda depurar y corregir con poco esfuerzo. Esta guía tiene un recurso/punto final ( products ) para obtener datos de la products mesa. Siga los pasos a continuación para crear una clase para el recurso:

  1. abrir un nuevo products.js archivo en un editor de texto:

                              
                                $ nano products.js
    
                              
                            
  2. Enter la siguiente información en el products.js expediente.

                              
                                class products {
    
        constructor(dg) {
            this.dg = dg;        
        }
    
        insertRecord(jsonData, callBack) {
    
            var sql = "insert into products (product_name, retail_price) values (?, ?)"; 
    
            var params = [];
    
            params.push(jsonData["product_name"]);  
            params.push(jsonData["retail_price"]); 
    
            this.dg.execute(sql, params, callBack);          
        }
    
        getRecords(resourceId, callBack) {
    
             var sql = "select product_id, product_name, retail_price from products";
    
             var params = []; 
    
             if (resourceId != "") {
                 sql = sql + " where product_id = ?";               
                 params.push(resourceId);    
             }
    
             this.dg.query(sql, params, callBack);
        }
    
        updateRecord(resourceId, jsonData, callBack) {
    
            var sql = "update products set product_name = ?, retail_price = ? where product_id = ?";
    
            var params = [];
    
            params.push(jsonData["product_name"]);  
            params.push(jsonData["retail_price"]); 
            params.push(resourceId); 
    
            this.dg.execute(sql, params, callBack);
        }
    
        deleteRecord(resourceId, callBack) {
    
            var sql = "delete from products where product_id = ?";
    
            var params = [];
    
            params.push(resourceId);   
    
            this.dg.execute(sql, params, callBack);       
        }
    }
    
    module.exports = products;
    
                              
                            
  3. Guardar y close la products.js archivo cuando haya terminado con la edición.

los products.js archivo explicado:

  • los products{} La clase envuelve todo el método del recurso en un solo archivo.

                              
                                class products {
        ...
    }
    
                              
                            
  • los constructor (dg) {..} método acepta uno dg argumento. los dg se refiere a su anterior database_gateway clase que expone las diferentes funciones de la base de datos.

  • los this.dg = dg; instrucción inicializa una nueva propiedad de clase ( dg ) y asigna el valor de la database_gateway objetar la propiedad.

  • los products{...} La clase presenta otros cuatro métodos que corresponden a las operaciones CRUD:

    • insertRecord(jsonData, ...) : acepta una carga JSON (jsonData) y construye un INSERT declaración.

    • getRecords(resourceId, ...) : acepta un resourceId parámetro y construye un SELECT declaración. Cuando defines el resourceId durante una llamada HTTP, MySQL solo devuelve el producto que coincide con el resourceId valor.

    • updateRecord(resourceId, jsonData, ...) : acepta un resourceId y una carga JSON y construye un UPDATE comando para cambiar el registro que coincide con el resourceId .

    • deleteRecord(resourceId, ...) : acepta un resourceId y construye un DELETE comando para eliminar el registro que coincide con el resourceId .

  • Los cuatro métodos CRUD pasan un callBack función a la database_gateway clase usando el this.dg.query(sql, params, callBack); y this.dg.execute(sql, params, callBack); declaraciones. los callBack() La función se ejecuta cuando se completan las operaciones.

  • los module.exports = products; línea al final le permite usar la clase en otros archivos usando el require('./products.js'); declaración.

4. Crea un http_requests Clase

Este paso describe la creación de un http_requests clase que devuelve la mayoría de las variables HTTP requeridas en este proyecto.

  1. abrir un nuevo http_requests.js en un editor de texto.

                              
                                $ nano http_requests.js
    
                              
                            
  2. Enter la siguiente información en el http_requests.js expediente.

                              
                                class http_requests {
    
        constructor(httpRequest) {
    
            var url = require("url");
    
            this.httpRequest = httpRequest;
    
            var pathname = url.parse(this.httpRequest.url).pathname;
    
            this.resourcePath = pathname.split("https://www.vultr.com/");
            this.resourceId   = "";
            this.httpMethod   = httpRequest.method
    
            if (this.resourcePath.length >= 3) {
                this.resourceId = this.resourcePath[2]
            }   
        }
    
    }  
    
    module.exports = http_requests;
    
                              
                            
  3. Guardar y close la http_requests.js expediente.

los http_requests.js archivo explicado:

  • los http_requests clase envuelve las diferentes variables HTTP en un constructor(...) método.

                              
                                class http_requests {
    
        constructor(httpRequest) {
    
        }
    }
    
                              
                            
  • los constructor(httpRequest){} método acepta un httpRequest objeto. Este objeto proviene de un http biblioteca que luego debe importar e incluir en un archivo diferente.

  • los pathname.split("https://www.vultr.com/"); La función divide la URL usando el / carácter y devuelve el resourceId . Por ejemplo, si solicita la URL https://127.0.0.1:8080/products/3 la pathname.split("https://www.vultr.com/"); función devuelve 3 como el resourceId . el lógico if (this.resourcePath.length >= 3) {...} declaración asegura la resourceId está disponible en la URL de solicitud.

5. Crea un main.js Expediente

Su Node.js requiere un archivo principal que se ejecuta cuando se inicia la aplicación. El archivo principal es el punto de entrada a su aplicación. Siga los pasos a continuación para crear el archivo:

  1. abrir un nuevo main.js en un editor de texto.

                              
                                $ nano main.js
    
                              
                            
  2. Enter la siguiente información en el main.js expediente.

                              
                                var db_gateway    = require('./db_gateway.js');
    var http_requests = require('./http_requests.js');
    var products      = require('./products.js');   
    
    const http = require('http');
    const hostname="127.0.0.1";
    const port = 8080;
    
    const server = http.createServer((req, res) => { 
    
        var dg = new db_gateway();
        var httpRequest = new http_requests(req);
        var product = new products(dg); 
    
        var payload = "";            
    
        req.on('data', function (data) {
            payload += data;
        });      
    
        req.on('end', function () {
    
            function callBack(err, result) {
    
                res.statusCode = 200;
    
                res.setHeader('Content-Type', 'application/json');
    
                var response = {}
    
                if (err) { 
                    response["error"] = err.message;
                } else {
                    response["data"] = result; 
                }
    
                res.write(JSON.stringify(response, null, 4));
                res.end();
            }
    
            resourceId = httpRequest.resourceId;
    
            switch (req.method) { 
    
                case "POST":
    
                    jsonData =  JSON.parse(payload); 
    
                    product.insertRecord(jsonData, callBack);
    
                    break;
    
                case "PUT": 
    
                    jsonData =  JSON.parse(payload); 
    
                    product.updateRecord(resourceId, jsonData, callBack);
    
                    break;
    
                case "DELETE": 
    
                    product.deleteRecord(resourceId, callBack);
    
                    break; 
    
                case "GET":  
    
                    product.getRecords(resourceId, callBack); 
    
                    break; 
            }
    
        });
    });
    
    server.listen(port, hostname, () => {
        console.log(`Server running at https://${hostname}:${port}/`);
    });
    
                              
                            
  3. Guardar y close la main.js expediente.

El archivo main.js explicó:

  • Las primeras tres líneas importan todas las clases que ha creado para este proyecto.

                              
                                var db_gateway    = require('./db_gateway.js');
    var http_requests = require('./http_requests.js');
    var products      = require('./products.js');   
    
                              
                            
  • Las siguientes líneas importan el http módulo. los http El módulo ejecuta un servidor web que escucha las conexiones HTTP entrantes en el puerto 8080 .

                              
                                const http = require('http');
    const hostname="127.0.0.1";
    const port = 8080;
    
                              
                            
  • La siguiente instrucción inicia un servidor HTTP.

                              
                                ...
    
    const server = http.createServer((req, res) => { 
        ...
    });
    
    ...
    
                              
                            
  • Las siguientes líneas crean los nuevos objetos a partir de las clases importadas.

                              
                                ...
    
    var dg = new db_gateway();
    var httpRequest = new http_requests(req);
    var product = new products(dg);
    
    ... 
    
                              
                            
  • El seguimiento callBack() La función se ejecuta cuando su aplicación completa las operaciones CRUD. los callBack() La función muestra la respuesta en formato JSON.

                              
                                ...
    
    function callBack(err, result) {
    
        res.statusCode = 200;
    
        res.setHeader('Content-Type', 'application/json');
    
        var response = {}
    
        if (err) { 
            response["error"] = err.message;
        } else {
            response["data"] = result; 
        }
    
        res.write(JSON.stringify(response, null, 4));
        res.end();
    }
    
    ...
    
                              
                            
  • los switch() {} instrucción examina el método HTTP ( req.method ) y empareja los métodos con los correctos. product's métodos para completar las operaciones HTTP según la siguiente lista:

    • POST : ejecuta el product.insertRecord(jsonData, callBack); declaración.

    • PUT : ejecuta el product.updateRecord(resourceId, jsonData, callBack); declaración.

    • DELETE : ejecuta el product.deleteRecord(resourceId, callBack); declaración.

    • GET : ejecuta el product.getRecords(resourceId, callBack); declaración.

6. Pruebe la aplicación CRUD de Node.Js

La aplicación ya está lista para la prueba. Su base de datos y archivos de código fuente están en su lugar. Ejecute los pasos a continuación para inicializar el directorio de su proyecto Node.js, descargar los módulos necesarios y ejecutar pruebas usando Linux curl dominio:

  1. Inicializa el directorio de tu proyecto.

                              
                                $ npm init
    
                              
                            

    Enter las siguientes respuestas:

                              
                                package name: (project) : Press ENTER to leave as default.
    
    version: (1.0.0) : Press ENTER to leave as default.
    
    description: Press ENTER to leave as default.
    
    entry point: (main.js) Press ENTER to leave as default.
    
    test command: Press ENTER to leave as default.
    
    git repository: Press ENTER to leave as default.
    
    keywords: Press ENTER to leave as default.
    
    author: Press ENTER to leave as default.
    
                              
                            

    licencia: (ISC) Pulse ENTER para dejar por defecto.

    El paquete Node.js npm muestra la siguiente respuesta.

                              
                                About to write to /home/francis/project/package.json:
    
    {
      "name": "project",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    
    Is this OK? (yes)
    
                              
                            

    Teclear y presione ENTER para confirmar los cambios.

  2. Use el administrador de paquetes de Node.js ( npm ) para descargar e importar el mysql biblioteca en su proyecto.

                              
                                $ npm install mysql
    
                              
                            

    Producción.

                              
                                npm notice created a lockfile as package-lock.json. You should commit this file.
    npm WARN [email protected] No description
    npm WARN [email protected] No repository field.
    
    + [email protected]
    added 11 packages from 15 contributors and audited 11 packages in 1.079s
    found 0 vulnerabilities
    
                              
                            
  3. ejecutar el main.js archivo usando el node dominio. El siguiente comando establece un servidor HTTP que escucha las conexiones entrantes en el puerto 8080 . los node main.js El comando tiene una función de bloqueo. Por lo tanto, no ejecute ningún otro comando en su ventana de terminal activa.

                              
                                $ node main.js
    
                              
                            

    Producción.

                              
                                Server running at https://127.0.0.1:8080/
    
                              
                            
  4. Establezca una nueva conexión SSH a su servidor en una segunda ventana de terminal y use curl para ejecutar las siguientes operaciones CRUD:

    • Create operation : añade un nuevo registro a la products mesa.

                                    
                                      $ curl -X POST https://127.0.0.1:8080/ -H 'Content-Type: application/json' -d '{"product_name":"DOUBLE-SIDED TAPE","retail_price": 4.95}'
      
                                    
                                  

      Producción.

                                    
                                      {
          "data": "Success"
      }
      
                                    
                                  
    • Read operation - all records : recupera registros de la products mesa.

                                    
                                      $ curl -X GET https://127.0.0.1:8080/products 
      
                                    
                                  

      Producción.

                                    
                                      {
          "data": [
              {
                  "product_id": 1,
                  "product_name": "LEATHER BELT",
                  "retail_price": 18.45
              },
              {
                  "product_id": 2,
                  "product_name": "BLUETOOTH SPEAKER",
                  "retail_price": 75.95
              },
              {
                  "product_id": 3,
                  "product_name": "RECHARGEABLE TORCH",
                  "retail_price": 35.85
              },
              {
                  "product_id": 4,
                  "product_name": "DOUBLE-SIDED TAPE",
                  "retail_price": 4.95
              }
          ]
      }
      
                                    
                                  
    • Read operation - one record : recupera un registro de la products tabla que coincide con un resourceId al final de la URL (por ejemplo, 4 ).

                                    
                                      $ curl -X GET https://127.0.0.1:8080/products/4
      
                                    
                                  

      Producción.

                                    
                                      {
          "data": [
              {
                  "product_id": 4,
                  "product_name": "DOUBLE-SIDED TAPE",
                  "retail_price": 4.95
              }
          ]
      }
      
                                    
                                  
    • Update operation : modifica los detalles de un producto que coincide con el resourceId (Por ejemplo, 3 ).

                                    
                                      $ curl -X PUT https://127.0.0.1:8080/products/3 -H 'Content-Type: application/json' -d '{"product_name":"RECHARGEABLE LED TORCH","retail_price": 40.20}'
      
                                    
                                  

      Producción.

                                    
                                      {
          "data": "Success"
      }
      
                                    
                                  

      Solicita el producto ( product_id 3 ) para verificar si el comando de actualización fue exitoso.

                                    
                                         $ curl -X GET https://127.0.0.1:8080/products/3
      
                                    
                                  

      Producción.

                                    
                                      {
          "data": [
              {
                  "product_id": 3,
                  "product_name": "RECHARGEABLE LED TORCH",
                  "retail_price": 40.2
              }
          ]
      }
      
                                    
                                  
    • Delete Operation : elimina un producto que coincide con el resourceId (Por ejemplo, 4 ).

                                    
                                      $ curl -X DELETE https://127.0.0.1:8080/products/4
      
                                    
                                  

      Producción.

                                    
                                          {
              "data": "Success"
          } 
      
                                    
                                  

      Consulte el producto nuevamente para verificar si la operación de eliminación fue exitosa.

                                    
                                          $ curl -X GET https://127.0.0.1:8080/products/4
      
                                    
                                  

      Producción.

                                    
                                          {
              "data": []
          }
      
                                    
                                  

Los resultados anteriores muestran que su aplicación CRUD de Node.js funciona como se esperaba.

Conclusión

Esta guía es un recorrido completo para implementar una aplicación CRUD con Node.js y el servidor de base de datos MySQL en Ubuntu 20.04. Utilice el conocimiento de esta guía para codificar su próximo proyecto de Node.js. Puede agregar tantos puntos finales/recursos en su aplicación Node.js según la complejidad de su proyecto. Recuerde separar cada recurso en un archivo de clase diferente para facilitar el soporte futuro.

Título del artículo Nombre (opcional) Correo electrónico (opcional) Descripción

Enviar sugerencia

Related Posts