Como construir una API con Node.js y PostgreSQL
Emanuelly Leoncio. Nest.js es un framework Node.js que permite desarrollar aplicaciones backend eficientes, escalables y organizadas. Por defecto, usa TypeScript o JavaScript.
En este tutorial, crearemos una API con Nest.js, PostgreSQL y PrismaORM. Esta API simulará un sistema de tienda de ropa (store) y en él agregaremos y manipularemos registros de ropa (clothes) y sus marcas (brands). Trabajaremos con los endpoints GET, POST, PUT y DELETE.
Instalación y preparación del proyecto
En primer lugar, necesitarás tener Node y npm instalados en tu computadora. Con ellos instalados, podemos continuar con el tutorial.
Si no tienes Nest.js instalado, puedes ejecutar el siguiente comando en la terminal:
Ahora, comencemos un nuevo proyecto. Nuestra API se llamará store-nestjs.
Para abrir el proyecto en VSCode, ejecuta:
A continuación:
Notarás que tenemos la siguiente estructura de carpetas:
Hablando brevemente de cada uno:
- main.ts: punto de entrada donde se inicia la aplicación;
- app.module.ts: módulo raíz, que importa y organiza todos los demás módulos;
- app.controller.ts: responsable de manejar las solicitudes entrantes y devolver las respuestas al cliente;
- app.service.ts: encapsula y gestiona la lógica de la aplicación. A través de él se puede reutilizar código, manteniendo una estructura organizada y desacoplada en toda la aplicación;
- pasta test e app.controller.spec.ts: archivos de prueba;
- .env: archivo utilizado para configurar variables de entorno.
Con VSCode abierto, eliminemos algunos archivos que no usaremos por ahora. Quitarlo:
- La carpeta test;
- Los archivos app.controller.spec.ts, app.controller.ts y app.service.ts.
Excluye también las importaciones, en app.module.ts, de los archivos anteriormente removidos:
El archivo app.module.ts quedara así:
PrismaORM
Prisma es una herramienta de mapeo relacional de objetos (ORM) y será responsable de crear y manipular la base de datos. Se puede acceder a su documentación aquí.
Para continuar con el tutorial, crearemos nuestra base de datos. Para ello instalaremos Prisma como dependencia de desarrollo.
Ahora, comencemos Prisma en el proyecto:
Después de ejecutar el comando anterior, notarás que el archivo schema.prisma se ha insertado en el proyecto.
Configuración de la conexión de la base de datos
En el archivo .env, introduciremos los datos para conectarnos con la base. Las variables de entorno serán las siguientes:
En:
- SU-USUARIO: pon el usuario desde tu configuración de postgres;
- SU-CONTRASEÑA: ingrese la contraseña para su configuración de postgres;
- NOME-BD: introduce el nombre de la base de datos. Aquí la llamaremos store_nestjs.
Crea la base de datos usando el siguiente SQL. Aquí usaremos Beekeeper.
Creación de las tablas
Primero vamos a crear la tabla brands. Nuestra tabla tendrá como atributos el id y el nombre de la marca.
En el archivo schema.prisma, agrega:
A continuación, crearemos la migration, un historial de lo que se crea y cambia en la base de datos. Entonces, ejecuta:
Ahora crearemos la tabla clothes. En esta tabla tendremos el id, el tipo y género de la ropa, un barcode y el ID de la marca, que será el enlace a la tabla brands.
Inserta en el schema.prisma:
Ejecuta nuevamente:
Observa que con cada cambio hecho se genera una nueva migration. Con esto ya tenemos todo el cronograma con cambios en nuestro banco.
Observa que en Beekeeper se generaron las tablas prisma_migrations, brands y clothes.
Creación del module
Vamos a crear un nuevo resource que traerá el controller, module y service para cada una de nuestras entidades, brand y clothe.
Ejecuta:
Durante la ejecución, aparecerán dos preguntas. Selecciona las siguientes opciones:
Realiza el mismo proceso con brand.
Remueve los archivos de prueba según se ve en la siguiente figura:
Creación del DTO
Para la mejor organización del proyecto y para mantener las responsabilidades separadas, trabajaremos con el estándar DTO (Data Transfer Object). Crea los archivos brand.dto.ts y clothe.dto.ts en cada carpeta respectiva. En estos archivos detallaremos los datos a manipular y sus tipos (los mismos atributos que las tablas que creamos anteriormente).
Inserta este código en brand.dto.ts:
En clothe.dto.ts:
PrismaService
Crea el archivo prismaService.ts dentro de src:
Agrega el código:
Ahora importa este service creado en cada uno de los modules:
CRUD
Después de toda esta preparación, comencemos nuestro CRUD. Toda la lógica de la “regla de negocio” de nuestra aplicación estará concentrada en el servicio de cada entidad, en este caso, brand y clothe.
Endpoint POST
Para brand y clothe, crearemos una función asincrónica llamada create. En ella, primero comprobamos si los datos que se enviarán en el body de ka requisición ya existen. De ser así, devolverá un mensaje de error. De lo contrario, se crearán nuevos datos.
En brand tendremos:
En clothe:
Enseguida, ajustamos los controllers de cada entidad, incluyendo post.
En clothe.controller:
En brand.controller:
Para dar start al proyecto, ejecuta:
Vamos a probar la ruta. En postman crearemos una marca en la ruta localhost:3000/brand:
Ahora, agregaremos algo de ropa, en la ruta localhost:3000/clothe:
Podemos ver en la base de datos que los registros fueron creados exitosamente:
Seguiremos igual con los demás endpoints.
Endpoint GET
En cada service, crearemos una función llamada findAll, que retornará todos los registros de la base de datos.
En clothe.service, añade:
En brand.service:
En los controllers haremos la llamada para la ruta GET:
En brand.service:
En clothe.service:
Ahora haremos la prueba en postman para ambas rutas:
En brand: localhost:3000/brand
En clothe: localhost:3000/clothe
Endpoint PUT
Esta ruta será la encargada de editar un registro. Para hacer esto, necesitamos pasar la identificación del registro como parámetro de ruta. Después de recibirlo, verificamos si esta identificación existe en el banco. Si es así, este registro se edita con la información pasada en el body de la requisición. Si no se encuentra, se devuelve un mensaje de error.
Insertamos esta lógica en el service de cada entidad.
En clothe.service, agrega:
En brand.service:
Finalmente, añade en el controller de cada uno la ruta put:
Para probar en postman, vamos a realizar la llamada pasando un id:
En clothe: localhost:3000/clothe/2
En brand: localhost:3000/brand/2
Endpoint Delete
En este último endpoint hay que prestar atención al siguiente detalle: toda la ropa está ligada a una marca. Así, estableceremos que una prenda no puede existir sin tener una marca vinculada a ella. Por lo tanto, al eliminar el registro de una marca, también se debe eliminar toda la ropa vinculada a ella. Los registros de ropa se pueden eliminar por separado.
Vamos a agregar esta regla a nuestros service:
En brand.service:
En clothe.service:
En cada controller, agrega la ruta delete:
Ahora realizaremos nuestras pruebas finales en postman.
En clothe: localhost:3000/clothe
En brand: localhost:3000/brand:
Así completamos con éxito nuestra solicitud.
Espero que esta guía haya sido de ayuda.
¡Éxito!
Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.