Prisma ORM + Express + Typescript (API REST)
En esta guía práctica aprenderemos a trabajar con Prisma ORM en un proyecto de Node.js con Express y TypeScript. Construiremos una API REST que nos permitirá interactuar con una base de datos SQLite utilizando Prisma como ORM. A lo largo de la guía, veremos cómo configurar Prisma en nuestro proyecto, definir los modelos de la base de datos, crear migraciones, y realizar consultas a la base de datos utilizando Prisma y Express.
Tutorial en video 👇👇👇
¿Qué es Prisma?
Prisma es una herramienta de código abierto que nos permite interactuar con nuestra base de datos de una forma más sencilla y segura. Con Prisma, podemos escribir consultas en TypeScript y obtener un autocompletado de las tablas y campos de nuestra base de datos. Además, Prisma nos facilita la creación de migraciones y nos permite definir las relaciones entre las tablas de una forma sencilla y segura.
Recursos
Links
Extensiones VSCode (opcional):
- Material Icon Theme Personaliza los íconos de tus archivos y carpetas con este tema de íconos visualmente atractivo. Ideal para mejorar la navegación y organización de proyectos.
- Moonlight Un tema oscuro inspirado en colores suaves y relajantes, perfecto para sesiones de programación prolongadas.
- Pretty TypeScript Errors Transforma los errores de TypeScript en mensajes más claros y fáciles de entender, optimizando el proceso de depuración.
- Prisma Soporte oficial para trabajar con Prisma, un ORM que facilita la manipulación de bases de datos en proyectos TypeScript y JavaScript.
- SQLite Viewer Una herramienta para explorar bases de datos SQLite directamente desde Visual Studio Code, con una interfaz fácil de usar.
- Thunder Client Una alternativa ligera y rápida a Postman, diseñada para realizar pruebas de API directamente en el editor.
Instalación
npm init -y
npm i -D typescript tsx @types/node
tsconfig.json
npx tsc --init
Prisma
npm i -D prisma
Configurar Prisma ORM con SQLite
npx prisma init --datasource-provider sqlite
Los modelos en el esquema Prisma tienen dos propósitos principales:
- Definir la estructura de la base de datos
- Definir las relaciones entre las tablas
prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
Migraciones
npx prisma migrate dev --name init
Este comando hizo tres cosas:
- Se creó un nuevo archivo de migración SQL para esta migración en el prisma/migrationsdirectorio.
- Ejecutó el archivo de migración SQL contra la base de datos.
- Se ejecutó prisma generatebajo el capó (que instaló el @prisma/clientpaquete y generó una API de cliente Prisma personalizada en función de sus modelos).
Express y Prisma
package.json
{
"name": "01-prisma",
"version": "1.0.0",
"scripts": {
"dev": "tsx --watch src/server.ts"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/node": "^22.10.2",
"prisma": "^6.0.1",
"tsx": "^4.19.2",
"typescript": "^5.7.2"
},
"dependencies": {
"@prisma/client": "^6.0.1",
"express": "^4.21.2"
}
}
npm i express
src/config/prisma.ts
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();
src/server.ts
import express from "express";
import postRouter from "./routes/post.route";
import userRouter from "./routes/user.route";
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.use("/api/v1/users", userRouter);
app.use("/api/v1/posts", postRouter);
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
src/routes/user.route.ts
import { Router } from "express";
import { prisma } from "../config/prisma";
const userRouter = Router();
// /api/v1/users
userRouter.get("/", async (req, res) => {
try {
const users = await prisma.user.findMany();
res.json({ users });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
});
userRouter.post("/", async (req, res) => {
try {
const { name, email } = req.body;
const user = await prisma.user.create({
data: {
name,
email,
},
});
res.json({ user });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
});
export default userRouter;
import { Router } from "express";
import { prisma } from "../config/prisma";
const postRouter = Router();
// /api/v1/posts
postRouter.get("/", async (req, res) => {
try {
const posts = await prisma.post.findMany();
res.json({ posts });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
});
postRouter.post("/", async (req, res) => {
try {
const { title, content, authorEmail } = req.body;
const post = await prisma.post.create({
data: {
title,
content,
author: {
connect: { email: authorEmail },
},
},
});
res.json({ post });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
});
export default postRouter;
Conclusiones
Prisma es una herramienta muy útil para trabajar con bases de datos en proyectos de Node.js. Nos permite escribir consultas en TypeScript y nos ofrece un autocompletado de las tablas y campos de nuestra base de datos. Además, Prisma nos facilita la creación de migraciones y nos permite definir las relaciones entre las tablas de una forma sencilla y segura. Sin duda, Prisma es una excelente opción para trabajar con bases de datos en proyectos de Node.js.