Cómo construir una API CRUD REST de Nest.js usando TypeORM y PostgreSQL
Siga este tutorial para conocer algunas tecnologías complementarias interesantes que puede utilizar en su próximo proyecto.
Al igual que otros marcos de Node.js, Nest.js proporciona un conjunto de herramientas completo para crear servicios backend sólidos y escalables. No obstante, es importante comprender cómo implementar las operaciones de creación, lectura, actualización y eliminación (CRUD) en Nest.js de manera eficiente; estas son las operaciones más fundamentales en el desarrollo de API.
Aprenda a crear una API CRUD REST de Nest.js utilizando TypeORM y una base de datos PostgreSQL.
Primeros pasos con Nest.js
Para comenzar, instale la herramienta de línea de comandos Nest.js:
npm i -g @nestjs/cli
A continuación, cree un nuevo proyecto ejecutando:
nest new crud-app
La herramienta CLI le pedirá que elija un administrador de paquetes, elija la opción que considere más preferible. Usaremos npm, el administrador de paquetes de Node.
La CLI creará un proyecto básico de Nest.js con todos los archivos de configuración necesarios y las dependencias iniciales necesarias para ejecutar la aplicación.
Finalmente, navegue hasta el directorio del proyecto e inicie el servidor de desarrollo.
cd crud-app
npm run start
Puedes encontrar el código de este proyecto en su repositorio de GitHub.
Crear una base de datos PostgreSQL
Este tutorial utiliza una instancia de PostgreSQL en la nube, pero en su lugar puede configurar una base de datos de PostgreSQL local. Puede instalar PostgreSQL en Windows, macOS o Linux.
Para configurar una instancia de PostgreSQL en la nube:
Dirígete a ElephantSQL, regístrate e inicia sesión en la página de descripción general de tu cuenta.
Haga clic en el botón Crear nueva instancia en la sección superior izquierda de la página para crear una nueva instancia para su aplicación.
- Complete el nombre de su instancia, elija el plan gratuito y finalmente seleccione la región para completar el proceso de configuración.
- Después de crear la instancia de la base de datos, vaya a la página configuración y copie la URL de la base de datos proporcionada.
Configurar la conexión de la base de datos
En el directorio raíz de su proyecto, cree un archivo .env y pegue la URL de conexión de la base de datos de la siguiente manera:
DATABASE_URL="<your connection url here>"
Ahora instale estos paquetes:
npm install pg typeorm @nestjs/typeorm @nestjs/config
A continuación, continúe y cree un módulo de base de datos utilizando la herramienta CLI.
nest g module database
Abra el archivo database/database.module.ts y agregue el siguiente código de configuración de la base de datos:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../users/models/user.entity';
@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
type: 'postgres',
url: configService.get('DATABASE_URL'),
entities: [User],
synchronize: true
}),
}),
],
})
export class DatabaseModule {}
Este módulo de base de datos maneja la conexión configurando el módulo TypeORM con el parámetro de conexión requerido, la URL de la base de datos.
Además, define la entidad Usuario como parte de la configuración que especifica la estructura y propiedades de los datos almacenados en la tabla de la base de datos PostgreSQL.
En esta etapa, su código probablemente arrojará un error porque aún no ha creado la entidad de usuarios. Lo harás en los siguientes pasos.
Actualice el archivo app.module.ts
Por último, actualice el módulo de la aplicación principal para incluir la configuración del módulo de base de datos.
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
}),
DatabaseModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Definir un módulo de usuarios
El módulo de usuarios sirve como un componente centralizado, responsable de encapsular y administrar la lógica necesaria para implementar la funcionalidad CRUD de la API.
Ejecute este comando de terminal para crear el módulo de usuarios de la API.
nest g module users
La herramienta CLI actualiza automáticamente el archivo app.module.ts para reflejar los cambios realizados, además de crear el módulo de usuario. Esto garantiza que el módulo recién creado, usuarios, se integre correctamente en la configuración del módulo de la aplicación.
Crear una entidad de usuario
TypeORM es una biblioteca de mapeo relacional de objetos (ORM) que simplifica las interacciones de bases de datos en aplicaciones que usan TypeScript al asignar objetos JavaScript a tablas de bases de datos.
Al crear una entidad de usuario usando TypeORM, define la estructura y las propiedades de los datos del usuario en la base de datos PostgreSQL.
En el directorio de usuarios, cree un nuevo models/user.entity.ts y agregue el siguiente código.
import { Entity, PrimaryGeneratedColumn, Column, } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
La entidad Usuario define la estructura de los datos del usuario almacenados en la base de datos. En este caso, se trata del id como columna de clave principal, y las columnas nombre y correo electrónico y sus propiedades correspondientes.
Crear el servicio API CRUD
Ahora, cree el servicio API que administrará la lógica de las operaciones CRUD ejecutando el siguiente comando:
nest g service users
Abra el archivo user-auth.service.ts y agregue este código:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import {User} from './models/user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.userRepository.find();
}
async findOne(id: number): Promise<User> {
return this.userRepository.findOne({ where: { id } });
}
async create(user: Partial<User>): Promise<User> {
const newuser = this.userRepository.create(user);
return this.userRepository.save(newuser);
}
async update(id: number, user: Partial<User>): Promise<User> {
await this.userRepository.update(id, user);
return this.userRepository.findOne({ where: { id } });
}
async delete(id: number): Promise<void> {
await this.userRepository.delete(id);
}
}
Esta clase UsersService define varios métodos API dedicados a manejar operaciones CRUD. Estos métodos incluyen recuperar los datos de todos los usuarios, encontrar un usuario específico usando su número de identificación, crear un nuevo usuario, actualizar un usuario existente y un método para eliminar los datos de un usuario específico en la base de datos.
Definir un controlador para la API
Cree un controlador que administre los puntos finales de API para las operaciones relacionadas con el usuario.
nest g controller users
A continuación, agregue el siguiente código al archivo users.controller.ts.
import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './models/user.entity';
@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
async findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Post()
@HttpCode(201)
async create(@Body() user: User): Promise<User> {
const createdUser = await this.usersService.create(user);
return createdUser;
}
@Put(':id')
async update (@Param('id') id: number, @Body() user: User): Promise<any> {
await this.usersService.update(id, user);
return { message: 'User updated successfully' };
}
@Delete(':id')
async delete(@Param('id') id: number): Promise<any> {
const user = await this.usersService.findOne(id);
if (!user) {
throw new NotFoundException('User does not exist!');
}
await this.usersService.delete(id);
return { message: 'User deleted successfully' };
}
}
El controlador gestiona los puntos finales API para las operaciones del usuario. Maneja solicitudes GET para recuperar a todos los usuarios, solicitudes POST para crear nuevos usuarios, solicitudes PUT para actualizar usuarios existentes y solicitudes DELETE para eliminar usuarios.
Al utilizar el UsersService e interactuar con la entidad Usuario, este controlador proporciona una API completa para administrar operaciones relacionadas con el usuario sobre los datos almacenados en la base de datos.
Actualizar el archivo users.module.ts
Por último, actualice el archivo users.module.ts como se muestra a continuación para asegurarse de incorporar la entidad de usuario y el módulo TypeORM, que establece la conexión a la base de datos.
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './models/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService]
})
export class UsersModule {}
Finalmente, continúe y active el servidor de desarrollo para probar las operaciones CRUD usando Postman.
npm run start
El servidor se iniciará en el puerto 3000 y podrá enviarle solicitudes API en http://localhost:3000/api/users.
Creación de aplicaciones backend con Nest.js
Ya sea que esté desarrollando una API REST simple o una aplicación web compleja, Nest.js ofrece un conjunto integral de características y capacidades para construir un sistema backend confiable y sólido.
Nest.js ofrece un enfoque más estructurado para el desarrollo de proyectos que Express.js. Esto garantiza que pueda crear, escalar y mantener aplicaciones complejas con confianza, gracias a su patrón de diseño organizado y modular.