Skip to content

¿Qué es un DTO? ​

Un DTO (Data Transfer Object, u objeto de transferencia de datos) es una clase que define los datos que una aplicación recibe o devuelve al comunicarse con otra parte del sistema, por ejemplo, mediante una API HTTP.

Su objetivo es transportar únicamente los datos necesarios para una operación, con una estructura clara y controlada.

csharp
public class PedidoCalculoDto
{
    public List<LineaPedidoDto> Lineas { get; set; } = new();
}

public class LineaPedidoDto
{
    public int ProductoId { get; set; }
    public int Cantidad { get; set; }
    public decimal Descuento { get; set; }
}

En este ejemplo, el DTO representa los datos que necesita la API para calcular un pedido. No necesita incluir todos los campos de las entidades Pedido o PedidoDetalle.

¿Por qué no reutilizar una entidad de Entity Framework? ​

Una entidad representa un concepto del dominio y suele estar relacionada con la persistencia en la base de datos. Un DTO, en cambio, representa los datos necesarios para una comunicación u operación específica.

Por ejemplo, una entidad PedidoDetalle podría contener:

  • Id
  • PedidoId
  • ProductoId
  • Cantidad
  • PrecioUnit
  • Descuento
  • ImpuestoPorc
  • TotalLinea
  • Navegaciones como Pedido y Producto

Pero para calcular un pedido, el cliente podría necesitar enviar solamente:

  • ProductoId
  • Cantidad
  • Descuento

Enviar la entidad completa obliga al cliente a conocer campos que no necesita y puede permitir que intente enviar valores que deberían calcularse o controlarse en el servidor.

Ventajas de usar DTOs ​

  • Limitar los datos recibidos: el endpoint acepta solo los campos que necesita.
  • No confiar en valores calculados por el cliente: por ejemplo, el servidor puede consultar el precio y el impuesto reales del producto en la base de datos, en lugar de aceptar esos valores enviados desde JavaScript o Postman.
  • Separar la API de la base de datos: los cambios internos de una entidad no tienen por qué modificar automáticamente el formato de la API.
  • Definir validaciones específicas: un DTO puede incluir reglas adecuadas para una operación, como una cantidad mayor que cero.
  • Controlar la respuesta: una API puede devolver solo los datos útiles, sin exponer propiedades internas o relaciones innecesarias.

¿Por qué no usar un diccionario o un objeto anónimo? ​

Diccionario ​

Un Dictionary<string, object> permite representar datos con claves dinámicas, pero los nombres y tipos de los valores no quedan definidos de manera tan clara en una clase. Es más fácil introducir errores tipográficos o tener que comprobar tipos manualmente.

Es útil cuando las claves realmente son dinámicas; para una estructura conocida como las líneas de un pedido, normalmente un DTO es más claro.

Objeto anónimo ​

Un objeto anónimo resulta práctico para construir respuestas pequeñas dentro de un método:

csharp
return Ok(new
{
    Subtotal = subtotal,
    Impuestos = impuestos,
    Total = total
});

Sin embargo, no puede declararse como el tipo de una clase reutilizable para recibir un cuerpo JSON en el parámetro de una acción. Para una estructura de entrada conocida o una respuesta que se reutilizará, un DTO con nombre suele ser más mantenible.

¿Cuándo conviene crear un DTO? ​

Crea un DTO cuando una operación necesita una estructura de datos propia, distinta de la entidad completa, o cuando quieres controlar explícitamente el contrato de entrada o salida de una API.

No es obligatorio crear uno para cada objeto o método. Para una respuesta muy pequeña y puntual, un objeto anónimo puede ser suficiente. La decisión depende de la claridad, la reutilización y el control que necesites.

Ejemplo aplicado a Pedidos360 ​

El endpoint POST /api/pedidos/calcular puede recibir un PedidoCalculoDto con una lista de líneas. Cada línea incluye ProductoId, Cantidad y Descuento.

La API consulta los productos por ID y obtiene de la base de datos los precios y porcentajes de impuesto confiables. Después calcula los importes y devuelve un resultado como Subtotal, Impuestos y Total.

Así, el DTO expresa qué información necesita la operación, mientras que las entidades representan los datos que el sistema gestiona y persiste.

Regla para recordar ​

Entidad: representa datos del dominio que el sistema puede persistir.
DTO: representa los datos que una operación necesita recibir o devolver.
Objeto anónimo: sirve para construir una estructura puntual sin declarar una clase con nombre.