En este post, te guiaré paso a paso para configurar un proyecto utilizando NestJS con Prisma y PostgreSQL. Al finalizar, tendrás un entorno funcional donde podrás crear y gestionar bases de datos con facilidad.
Prerrequisitos
Antes de comenzar, asegúrate de tener lo siguiente instalado en tu sistema:
- Node.js > 18: Asegúrate de tener Node.js instalado. Puedes descargarlo Cómo instalar y usar NVM para gestionar versiones de Node.js en Ubuntu y Windows
- Editor de código: Te recomiendo Visual Studio Code, pero puedes usar cualquier otro que prefieras.
- Un gestor de paquetes como npm o yarn.
Pasos para implementar NestJS con base de datos
Configurar la base de datos PostgreSQL
Para esta practica vamos a requerir una base de datos PostgresQL, para ello tenemos preparados varios post en donde realizamos la instalación en
Crear un nuevo proyecto NestJS
Primero, crea un nuevo proyecto de NestJS utilizando el CLI de NestJS:
npm i -g @nestjs/cli
nestjs new proyecto-prisma
Selecciona el gestor de paquetes que prefieras (npm o yarn) cuando se te pida.
Nota: Revisa el post de Entorno de trabajo para NestJS e Instalación de NestJS para que puedas trabajar con este framework
Instalar Prisma, PostgreSQL client y otras dependencias
Desde la carpeta del proyecto: cd proyecto-prisma
npm install prisma --save-dev
npm install @prisma/client
npm install dotenv joi
Inicializar Prisma
Ejecutamos en la terminal
npx prisma init
Esto crea:
- Una carpeta
/prisma- Un archivo
schema.prisma
- Un archivo
- Un archivo
.envcon una variableDATABASE_URL - El archivo
prisma.config.tsen la raíz del proyecto
prisma/
└── schema.prisma
.env
Configurar la conexión a PostgreSQL
Abre el archivo .env y configura tu cadena de conexión PostgreSQL:
DATABASE_URL="postgresql://usuario:password@localhost:5432/nombredb?schema=public"
- ⚠️ Asegúrate de tener PostgreSQL corriendo y la base de datos creada.
- El archivo
prisma.config.tsnecesita agregarimport 'dotenv/config';para que pueda detectar correctamente el.env
Definir el esquema Prisma (prisma/schema.prisma)
Vamos a crear un modelo básico de usuario y post, para ello creamos lo siguiente:
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
posts Post[]
}
model Post {
id Int @default(autoincrement()) @id
title String
content String?
published Boolean? @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
Ejecutar migraciones
npx prisma migrate dev --name init
Esto:
- Crea las tablas en PostgreSQL
- Genera el cliente Prisma
- Sincroniza el esquema
Configurar variables de entorno
- Crearemos una carpeta llamada
config - Asegurar de que el .env este creado
Procedemos a crear el archivo envs.ts en config
import 'dotenv/config';
import * as joi from 'joi';
interface EnvVars {
PORT: number;
}
const envsSchema = joi
.object({
PORT: joi.number().required(),
})
.unknown(true);
const { error, value } = envsSchema.validate(process.env);
if (error) {
throw new Error(`Config validation error: ${error.message}`);
}
const envVars: EnvVars = value;
export const envs = {
port: envVars.PORT,
};
Procedemos a crear el index.ts en config
export * from './envs';
En el archivo main.ts
Quitamos process.env.PORT ?? 3000 y lo remplazamos por envs.port
...
import { envs } from 'config';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(envs.port);
}
..
Crear Prisma Service en NestJS
Crea el servicio:
nest generate service prisma
Edita src/prisma/prisma.service.ts:
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async enableShutdownHooks() {
this.$on('beforeExit', async () => {
await this.$disconnect();
});
}
}
Crear Prisma Module
nest generate module prisma
Edita src/prisma/prisma.module.ts:
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
Y agrégalo a app.module.ts:
import { PrismaModule } from './prisma/prisma.module';
@Module({
imports: [PrismaModule],
})
export class AppModule {}
Usar Prisma en un módulo (ejemplo User)
nest generate module users
nest generate service users
nest generate controller users
User Service
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
findAll() {
return this.prisma.user.findMany();
}
create(data: { email: string; name?: string }) {
return this.prisma.user.create({ data });
}
}
User Controller
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
@Post()
create(@Body() body: { email: string; name?: string }) {
return this.usersService.create(body);
}
}
Probar la aplicación
npm run start:dev
Prueba:
Prisma Studio (opcional pero recomendado)
npx prisma studio
Interfaz web para inspeccionar la BD.