Práctica: Crear un Schema para una API de E-commerce

Video
25 min~5 min lectura

Reproductor de video

Concepto clave

Diseñar un schema para una API de e-commerce en producción requiere pensar en escalabilidad, relaciones entre entidades y validaciones desde el inicio. Imagina que estás construyendo un centro comercial digital: necesitas tiendas (productos), clientes (usuarios), transacciones (pedidos) y un sistema de inventario que funcione en tiempo real. En Prisma, el schema define la estructura de tu base de datos usando un lenguaje declarativo que luego se traduce a SQL mediante migraciones.

La clave está en modelar las relaciones correctamente. Por ejemplo, un usuario puede tener múltiples pedidos, y cada pedido puede contener varios productos. Esto se representa con relaciones uno a muchos y muchos a muchos. En producción, debes evitar diseños que generen consultas ineficientes, como anidaciones excesivas o falta de índices en campos frecuentemente consultados.

Cómo funciona en la práctica

Vamos a crear un schema básico para un e-commerce con estas entidades: Usuario, Producto, Pedido y DetallePedido. Sigue estos pasos:

  1. Define el modelo Usuario con campos como id, email, nombre y una relación a Pedido.
  2. Crea el modelo Producto con id, nombre, precio, stock y categoría.
  3. Modela Pedido con id, fecha, estado y relaciones a Usuario y DetallePedido.
  4. Implementa DetallePedido como tabla de unión para la relación muchos a muchos entre Pedido y Producto, incluyendo cantidad y precioUnitario.

Antes de codificar, piensa en los índices: por ejemplo, agrega un índice único al email del usuario para evitar duplicados y mejorar búsquedas. En producción, esto reduce tiempos de consulta significativamente.

Código en acción

Aquí tienes un ejemplo funcional del schema.prisma:

// Modelo Usuario
model Usuario {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  nombre    String
  pedidos   Pedido[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

// Modelo Producto
model Producto {
  id        Int      @id @default(autoincrement())
  nombre    String
  precio    Float
  stock     Int      @default(0)
  categoria String
  detalles  DetallePedido[]
}

// Modelo Pedido
model Pedido {
  id        Int      @id @default(autoincrement())
  fecha     DateTime @default(now())
  estado    String   @default("pendiente")
  usuarioId Int
  usuario   Usuario  @relation(fields: [usuarioId], references: [id])
  detalles  DetallePedido[]
}

// Modelo DetallePedido (tabla de unión)
model DetallePedido {
  id         Int     @id @default(autoincrement())
  pedidoId   Int
  productoId Int
  cantidad   Int     @default(1)
  precioUnitario Float
  pedido     Pedido  @relation(fields: [pedidoId], references: [id])
  producto   Producto @relation(fields: [productoId], references: [id])
  @@unique([pedidoId, productoId])
}

Ahora, mejoremos el schema para producción agregando validaciones y un índice compuesto:

// Refactorización: Agregar validaciones e índices
model Usuario {
  id        Int      @id @default(autoincrement())
  email     String   @unique @db.VarChar(255)
  nombre    String   @db.VarChar(100)
  pedidos   Pedido[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  @@index([email]) // Índice para búsquedas rápidas
}

model Producto {
  id        Int      @id @default(autoincrement())
  nombre    String   @db.VarChar(200)
  precio    Float    @db.Decimal(10, 2)
  stock     Int      @default(0)
  categoria String   @db.VarChar(50)
  detalles  DetallePedido[]
  @@index([categoria]) // Índice para filtrar por categoría
}

Errores comunes

  • Olvidar relaciones bidireccionales: En Prisma, si defines una relación en un modelo, debes definirla en el otro. Por ejemplo, si Usuario tiene pedidos, Pedido debe tener un campo usuarioId y una relación a Usuario.
  • No usar tipos de datos apropiados para producción: Evita String sin límites; usa @db.VarChar(length) para controlar el almacenamiento y mejorar el rendimiento.
  • Ignorar índices en campos frecuentemente consultados: Campos como email o categoría deben tener índices para acelerar las queries en grandes volúmenes de datos.
  • Diseñar relaciones muchos a muchos sin tabla de unión explícita: En e-commerce, necesitas almacenar datos adicionales como cantidad y precio en DetallePedido; no uses la relación implícita de Prisma en este caso.
  • No planificar migraciones desde el inicio: Cambiar el schema después de desplegar requiere migraciones cuidadosas; prueba siempre en un entorno de staging primero.

Checklist de dominio

  1. ¿Definiste todos los modelos necesarios (Usuario, Producto, Pedido, DetallePedido) con sus campos básicos?
  2. ¿Estableciste las relaciones correctamente (uno a muchos, muchos a muchos) usando claves foráneas?
  3. ¿Agregaste índices a campos como email y categoría para optimizar consultas?
  4. ¿Usaste tipos de datos específicos (ej., @db.Decimal para precios) en lugar de tipos genéricos?
  5. ¿Incluiste campos de auditoría como createdAt y updatedAt en modelos críticos?
  6. ¿Validaste que el schema permita operaciones comunes como crear un pedido con múltiples productos?
  7. ¿Probaste el schema generando una migración y ejecutándola en una base de datos local?

Extiende el Schema para Incluir Reseñas de Productos

En este ejercicio, ampliarás el schema de e-commerce para soportar reseñas de productos, una funcionalidad común en plataformas de comercio electrónico. Sigue estos pasos:

  1. Crea un nuevo modelo llamado Resena con los siguientes campos: id, contenido, calificacion (del 1 al 5), usuarioId, productoId, y fechacreacion.
  2. Establece las relaciones: una Resena pertenece a un Usuario y a un Producto. Asegúrate de que Usuario y Producto tengan campos para acceder a sus reseñas (ej., resenas en Usuario y Producto).
  3. Agrega validaciones: calificacion debe ser un entero entre 1 y 5, y contenido debe tener un máximo de 500 caracteres.
  4. Implementa un índice compuesto en usuarioId y productoId para evitar que un usuario deje múltiples reseñas para el mismo producto.
  5. Genera una migración usando npx prisma migrate dev --name add_resenas y verifica que no haya errores.

Al final, tu schema debe permitir consultas como "obtener todas las reseñas de un producto con sus usuarios" de forma eficiente.

Pistas
  • Recuerda que en Prisma, las relaciones se definen en ambos modelos involucrados.
  • Usa @db.VarChar(500) para limitar el contenido de la reseña.
  • Considera agregar un campo de estado (ej., 'activa' o 'eliminada') para manejar moderación en producción.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.