Decoradores en entidades

Avanzado
Nest
Nest
Actualizado: 09/06/2025

En el mundo de la programación, un decorador es un patrón de diseño que te permite añadir funcionalidades o modificar el comportamiento de una clase, un método, una propiedad o un parámetro de forma dinámica. En TypeScript, y por extensión en frameworks como NestJS, los decoradores son funciones especiales que se aplican usando el símbolo @ antes de la declaración a la que modifican.

Cuando trabajas con bases de datos en NestJS, especialmente con TypeORM, los decoradores son esenciales. Son la herramienta principal para definir y configurar tus entidades, permitiendo mapear tus clases de TypeScript directamente a tablas de bases de datos y establecer las relaciones entre ellas de una manera declarativa e intuitiva.

Decoradores de Entidad y Columna

Estos decoradores son los pilares para definir la estructura básica de tus tablas:

  • @Entity(): Este decorador se coloca sobre una clase para marcarla como una entidad de base de datos. Puedes pasarle un nombre como argumento (ej., @Entity('usuarios')) para especificar el nombre de la tabla en la base de datos; si no lo haces, TypeORM usará el nombre de la clase en minúsculas.
  • @PrimaryGeneratedColumn(): Define una columna que será la clave primaria de tu tabla. Su valor se genera automáticamente (por ejemplo, con un auto-incremento o un UUID). Puedes especificar la estrategia de generación:
    • @PrimaryGeneratedColumn(): Por defecto, usa increment para MySQL/PostgreSQL.
    • @PrimaryGeneratedColumn('uuid'): Genera un UUID para la clave primaria.
  • @Column(): Define una columna regular en la base de datos. Puedes personalizarla con un objeto de opciones para especificar detalles como el tipo de datos, longitud, si es única, si es nula, etc.
    • Inferencia de tipo: Para tipos básicos de TypeScript como string, number o boolean, TypeORM suele inferir el tipo de columna de la base de datos (ej., VARCHAR, INT, BOOLEAN).
    • Especificación explícita: Para tipos más complejos (como Date, JSON) o para forzar un tipo de base de datos específico (ej., DECIMAL, TEXT para strings largos), es recomendable usar la opción type: @Column({ type: 'text' }).

Decoradores de Relaciones

TypeORM permite definir las interacciones entre tus entidades con los siguientes decoradores:

  • @OneToOne(): Establece una relación uno a uno entre dos entidades. Cada registro de una entidad se relaciona con un único registro de otra entidad. Requiere @JoinColumn() en el lado propietario para definir la columna de clave foránea.
  • @OneToMany() y @ManyToOne(): Se utilizan juntos para relaciones uno a muchos y muchos a uno. Una entidad "uno" puede tener múltiples entidades "muchos", pero cada entidad "muchos" pertenece a una única entidad "uno". @ManyToOne() se coloca en el lado que contiene la clave foránea.
  • @ManyToMany() y @JoinTable(): Establecen relaciones muchos a muchos. Múltiples registros de una entidad pueden estar relacionados con múltiples registros de otra entidad. @JoinTable() se coloca en uno de los lados de la relación (el propietario) y hace que TypeORM genere automáticamente una tabla intermedia (o tabla de unión) para gestionar esta relación.

Decoradores de Índices y Opciones Adicionales

Estos decoradores te dan un control más fino sobre la estructura de tu tabla y su comportamiento:

  • @Index(): Define un índice para una columna o un conjunto de columnas, lo que puede mejorar significativamente el rendimiento de las consultas.
  • @Unique(): Define una restricción única para una columna o un conjunto de columnas, asegurando que los valores en esas columnas no se repitan.
  • @CreateDateColumn(): Crea automáticamente una columna para rastrear la fecha y hora de creación de un registro.
  • @UpdateDateColumn(): Crea automáticamente una columna para rastrear la última fecha y hora de actualización de un registro.
  • @VersionColumn(): Crea una columna de versión para el control de concurrencia optimista. TypeORM incrementa este valor en cada actualización, ayudando a prevenir que múltiples usuarios sobrescriban los cambios de otros.

Decoradores de Herencia

TypeORM también soporta patrones de herencia para tus entidades, lo que te permite organizar tu código de manera más limpia:

  • @Inheritance() y @DiscriminatorColumn(): Se usan para establecer estrategias de herencia, como la estrategia "Single Table" (todas las clases heredadas se guardan en una única tabla, con una columna discriminatoria para diferenciar el tipo de entidad) o "Table per Class" (cada clase heredada tiene su propia tabla).

Ejemplo de Entidad Completa con Decoradores

Para que veas cómo se combinan estos decoradores, aquí tienes un ejemplo de una entidad User más completa, que incluye propiedades y relaciones:

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  OneToOne,
  OneToMany,
  ManyToMany,
  JoinColumn,
  JoinTable,
  CreateDateColumn,
  UpdateDateColumn,
  VersionColumn,
  Index,
  Unique,
} from 'typeorm';

// Suponemos que estas entidades existen o se definirán después
import { Profile } from './profile.entity'; // Para OneToOne
import { Photo } from './photo.entity';     // Para OneToMany
import { Category } from './category.entity'; // Para ManyToMany

@Entity('users') // Mapea esta clase a la tabla 'users'
@Unique(['email']) // Asegura que el email sea único en la tabla
export class User {
  @PrimaryGeneratedColumn('uuid') // ID primario generado como UUID
  id: string;

  @Column({ length: 100 }) // Columna 'name' de tipo VARCHAR con longitud 100
  @Index('user_name_index') // Crea un índice para esta columna para búsquedas rápidas
  name: string;

  @Column({ unique: true }) // Columna 'email', debe ser única
  email: string;

  @Column({ default: true }) // Columna 'isActive' con valor por defecto 'true'
  isActive: boolean;

  @OneToOne(() => Profile, profile => profile.user) // Relación 1:1 con Profile
  @JoinColumn() // User es el propietario de la relación (tendrá la FK de Profile)
  profile: Profile;

  @OneToMany(() => Photo, photo => photo.user) // Relación 1:N con Photo (un User tiene muchas Photos)
  photos: Photo[]; // La propiedad 'photos' en Photo apunta de vuelta a este User

  @ManyToMany(() => Category, category => category.users) // Relación N:M con Category
  @JoinTable({ name: 'users_categories' }) // User es el propietario, creará la tabla intermedia 'users_categories'
  categories: Category[];

  @CreateDateColumn() // Columna para la fecha de creación
  createdAt: Date;

  @UpdateDateColumn() // Columna para la última fecha de actualización
  updatedAt: Date;

  @VersionColumn() // Columna para el control de concurrencia optimista
  version: number;
}

Conclusión

Los decoradores en NestJS, especialmente en el contexto de las entidades de TypeORM, son una herramienta poderosa. Proporcionan una manera declarativa y elegante de definir metadatos y modificar el comportamiento de tus clases y sus miembros. Simplifican significativamente la tarea de mapear tus modelos de datos de TypeScript a tablas de base de datos, permitiendo que la definición del esquema y la lógica del modelo estén estrechamente integradas en un solo lugar, lo que resulta en un código más legible y mantenible.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Nest es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Nest

Explora más contenido relacionado con Nest y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender el concepto de decoradores en NestJS.
  • Explorar los decoradores utilizados en las entidades con TypeORM.
  • Aprender a utilizar los decoradores en las entidades.

Cursos que incluyen esta lección

Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje