Do you use unique DTOs per use case?
Updated by Brady Stroud [SSW] 3 months ago. See history
123
<introEmbed
body={<>
In Clean Architecture, it is normally better to have a unique Data Transfer Object (DTO) for each endpoint or use case.
While sharing DTOs across multiple endpoints might seem like a way to save some code, it often leads to several problems:
* **Unnecessary Data Transfer:** Endpoints sending more data than what is actually needed, this can lead to performance issues.
* **Increased Coupling:** When multiple endpoints share the same DTO, a change required by one endpoint can inadvertently affect others.
* **Developer Confusion:** Developers will find it hard to understand which properties are relevant for a specific endpoint, leading to potential misuse or misunderstanding of the data structure.
</>}
/>
By creating unique DTOs tailored to each endpoint's specific requirements, you ensure that:
- Endpoints only deal with the data they need.
- Performance is optimized by avoiding the transfer of superfluous data.
- Endpoints are decoupled, making them easier to develop, test, and maintain independently.
namespace Northwind.Trading.Application.Contracts.Models;public class OrderItemModel{public int OrderId { get; set; }public string CustomerId { get; set; }public DateTime OrderDate { get; set; }public decimal TotalAmount { get; set; }public OrderStatus Status { get; set; }/// <summary>/// Used for GetOrderListEndpoint. Ignore when updating/// </summary>public string? ShipFromCountry { get; set; }/// <summary>/// Used only for GetOrdersEndpoint./// </summary>public DateTimeOffset ModifiedDateUtc { get; set; }/// <summary>/// Detailed list of order items. Only for GetOrderDetails./// Not used for GetOrderList/// </summary>public List<OrderItemViewModel> OrderItems { get; set; } = [];}
❌ Figure: Figure: Bad example - `OrderViewModel` is used for multiple purposes (e.g., `GetOrderList`, `GetOrderDetails`, `CreateOrder`) and has accumulated many properties, making it hard to read and maintain.
namespace Northwind.Trading.Application.Contracts.OrderQueries.Models;public class GetOrderListItemDto{public int OrderId { get; set; }public string CustomerId { get; set; }public DateTime OrderDate { get; set; }public decimal TotalAmount { get; set; }public OrderStatus Status { get; set; }}
✅ Figure: Figure: Good example - A simple `OrderSummaryDto` designed specifically for an endpoint that lists orders.
Related rules
Need help?
SSW Consulting has over 30 years of experience developing awesome software solutions.