Introducción
PostgreSQL (abreviado como Postgres) es una de las bases de datos más utilizadas en la construcción de aplicaciones de software. Postgres es un sistema de gestión de bases de datos de propósito general, de código abierto, relacionado con objetos (RDBMS). Una de las ventajas de usar Postgres es su soporte para consultas relativas (SQL) y no relativas (NoSQL).
Una forma de conectar una base de datos a una aplicación web es a través del uso de un ORM (Object Relational Mapper). Un ORM actúa como una capa de comunicación entre su aplicación y la base de datos. El objetivo de este tutorial es explicar cómo puede usar Postgres en su aplicación Express a través del Sequelize ORM.
El Sequelize ORM se describe como:
Un moderno TypeScript y Node.js ORM para Oracle, Postgres, MySQL, MariaDB, SQLite y SQL Server, y más.
Un moderno TypeScript y Node.js ORM para Oracle, Postgres, MySQL, MariaDB, SQLite y SQL Server, y más.
La API podrá crear, listar, actualizar el estado de finalización y eliminar tareas.
Este tutorial es el primero de una próxima serie de tutoriales enfocados en el uso de bases de datos relacionales en Express usando Sequelize.
Precondiciones
Para continuar con este tutorial, necesitarás lo siguiente:
- Un editor de texto (por ejemplo, VS Code)
- Un cliente de API para probar los endpoints (por ejemplo, Postman)
- Node.js está instalado en su computadora
- Conocimientos básicos de Express
- Una instancia de Postgres que se ejecuta local o remotamente
Proyecto Instalación
Comenzaremos configurando los archivos y directorios adecuados para crear una aplicación Express e instalar los paquetes necesarios.
-
Create the project directory:
mkdir tasks-manager-api
-
Navigate to the project directory:
cd tasks-manager-api
-
Initialize the NPM package by running the following command to create a
package.json
file with default settings:npm init -y
-
Install Express and other core dependencies:
npm install express express-async-errors dotenv && npm install nodemon --save-dev
-
Install Postgres driver for Node.js:
npm install pg
-
Install Sequelize:
npm install sequelize
-
In the root directory, create the
models
andutils
folders:mkdir models utils
-
In the root directory, create a
.env
file, which will contain the server’s port number and the database URL of any Postgres instance:PORT=5000 DATABASE_URL=postgres://<user>:<password>@<host>:<port>/<database>
-
In the root directory, create the
index.js
file, which is the application entry point:touch index.js
-
Set up the command to run the local development server by editing the
scripts
object inpackage.json
:{ //… "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "nodemon index.js", "start": "node index.js" }, //… }
La estructura de la carpeta del proyecto debería ser así:
Configuración de Sequelize
Crear dos archivos en elutils
Dirección :config.js
ydb.js.
Variables del entorno de carga
En laconfig.js
archivo, cargue las variables ambientales desde el.env
El archivo que utiliza eldotenv
Después de exportar elPORT
yDATABASE_URL
variables para que puedan ser accesibles en otras partes de la aplicación.
Elconfig.js
El archivo debe tener los siguientes contenidos:
require('dotenv').config()
const PORT = process.env.PORT || 3000
const DATABASE_URL = process.env.DATABASE_URL
module.exports = {
PORT,
DATABASE_URL
}
Creación de Sequelize Instance
En ladb.js
archivo, crea una instancia Sequelize. Puede crear una instancia Sequelize pasando el URI de conexión de la base de datos (almacenado enDATABASE_URL
) al constructor Sequelize. Luego crea una funciónconnectToDB,
que probará la conexión a la base de datos llamando elauthenticate
Función: Por último, se exporta elconnectToDB
La función y la instancia Sequelize.
Elutils/db.js
El archivo debe tener los siguientes contenidos:
const Sequelize = require("sequelize");
const { DATABASE_URL } = require("./config");
const sequelize = new Sequelize(DATABASE_URL)
const connectToDB = async () => {
try {
await sequelize.authenticate()
console.log("Database connection established successfully.")
} catch (error) {
console.log("Unable to connect to the database:", error)
return process.exit(1)
}
return null
}
module.exports = {
connectToDB,
sequelize
}
Definición del modelo de tareas
Un modelo Sequelize es una representación de una tabla en la base de datos.Task
Modelo mediante la extensión de la secuenciaModel
La clase y la llamadaModel.init(attributes, options)
Funcionamiento .
En lamodels
directorio, crear eltask.js
Archivo con los siguientes contenidos:
const {Model, DataTypes} = require("sequelize")
const {sequelize} = require("../utils/db")
class Task extends Model {}
Task.init({
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: {
type: DataTypes.STRING,
allowNull: false
},
completed: {
type: DataTypes.BOOLEAN,
defaultValue: false
}
}, {
sequelize,
modelName: "Task",
timestamps: true,
underscored: true,
defaultScope: {
attributes: {
exclude: ["createdAt", "updatedAt"]
}
}
})
Task.sync()
module.exports = Task
Elattributes
Los parámetros determinan la estructura delTask
en la base de datos. elTask
El modelo tiene tres atributos:
- id: Un campo de números enteros que es una clave primaria que se incrementa automáticamente y se utiliza para identificar de manera única cada registro.
- Título: Un campo de cadena que representa el nombre de la tarea.
- Completado: El campo completado tiene un valor booleano que indica si la tarea se ha completado.
Eloptions
parámetro configura cómo Sequelize maneja el modelo.Task
El modelo tiene las siguientes opciones:
- sequelize: la instancia Sequelize creada anteriormente en utils/db.js.
- modeloNombre: El nombre de la tabla creada en la base de datos.
- Timestamps: Cuando se establece True, se agregan automáticamente los campos creados y actualizados al modelo.
- Subrayado: Cuando se establece True, convierte los campos de Caso de camello en Caso de serpiente en la base de datos.
- defaultScope: Excluye ciertos atributos por defecto cuando se realiza la consulta.
ElTask.sync()
La función sincroniza el modelo con la base de datos mediante la creación de la tabla si la tabla no existe.
Creación del servidor expreso
Por último, lo coloca todo juntos creando el servidor Express.index.js
archivo, se configura el middleware necesario, se definen las rutas de endpoint de la API y se ejecuta el servidor expreso.
Elstart
La función es responsable de inicializar el servidor Express.start
La función prueba primero la conexión a la base de datos llamando elconnectToDB()
Si la conexión es exitosa, se inicia el servidor Express, que escucha en el puerto especificado.
Elindex.js
El archivo tiene los siguientes contenidos:
require("express-async-errors");
const express = require("express");
const app = express();
const { PORT } = require("./utils/config");
const { connectToDB } = require("./utils/db");
const Task = require("./models/task");
// middlewares
app.use(express.json());
// routes
app.get("/api/tasks", async (req, res) => {
const tasks = await Task.findAll();
res.json({
message: "List of tasks",
tasks: tasks,
});
});
app.post("/api/tasks", async (req, res) => {
const { title } = req.body;
const task = await Task.create({ title });
res.status(201).json({
message: "Task created successfully",
task,
});
});
app.patch("/api/tasks/:id/toggle-completed", async (req, res) => {
const { id } = req.params;
const task = await Task.findByPk(id);
if (!task) {
return res.status(404).json({ message: "Task not found" });
}
task.completed = !task.completed;
await task.save();
res.json({
message: task.completed
? "Task marked as completed"
: "Task marked as not completed",
task,
});
});
app.delete("/api/tasks/:id", async (req, res) => {
const { id } = req.params;
const task = await Task.findByPk(id);
if (!task) {
return res.status(404).json({ message: "Task not found" });
}
await task.destroy();
res.json({
message: "Task deleted successfully",
});
});
const start = async () => {
try {
await connectToDB();
app.listen(PORT, console.log(`Server is running on port ${PORT}`));
} catch (error) {
console.error(error);
process.exit(1);
}
};
start();
Introducción al API Endpoint
Ahora puede proceder a probar los puntos finales de la API:
- Crear una nueva tarea—POST /api/tasks:
- Lista de todas las tareas—GET /api/tasks:
- Toggle estado de finalización—PATCH /api/tasks/:id/toggle-completado:
- Eliminar una Tareas—DELETE /api/task:
Conclusión
Ahora sabes cómo conectar una aplicación Express a una base de datos de Postgres utilizando Sequelize.Has construido una API de gestor de tareas simple, y en el proceso, has configurado Sequelize, conectado Sequelize a una instancia de Postgres, definido laTask
modelo, y creó los puntos finales de API.
Actualmente, la lógica del controlador está escrita en laindex.js
En los próximos tutoriales, refactorizaremos esta base de códigos en una estructura más escalable utilizando controladores, routers y migraciones Sequelize.
Para seguir leyendo, debes pasar por laDocumentación Secundariapara obtener más información sobre consultas de modelo, validaciones, asociaciones y más.
Puedes encontrar el código fuente completo para este tutorial enGitHub.
Recursos
- Documentación de secuelación (v6)
- ¿Qué es PostgreSQL?
- Usando bases de datos relacionales con Sequelize – FullStackOpen
- Documentación Express.js