Recent from talks
Nothing was collected or created yet.
Data transfer object
View on WikipediaIn the field of programming a data transfer object (DTO[1][2]) is an object that carries data between processes. The motivation for its use is that communication between processes is usually done resorting to remote interfaces (e.g., web services), where each call is an expensive operation.[2] Because the majority of the cost of each call is related to the round-trip time between the client and the server, one way of reducing the number of calls is to use an object (the DTO) that aggregates the data that would have been transferred by the several calls, but that is served by one call only.[2]
The difference between data transfer objects and business objects or data access objects is that a DTO does not have any behavior except for storage, retrieval, serialization and deserialization of its own data (mutators, accessors, serializers and parsers). In other words, DTOs are simple objects that should not contain any business logic but may contain serialization and deserialization mechanisms for transferring data over the wire.[1]
This pattern is often incorrectly used outside of remote interfaces. This has triggered a response from its author[3] where he reiterates that the whole purpose of DTOs is to shift data in expensive remote calls.
Terminology
[edit]A value object is not a DTO. The two terms have been conflated by Sun/Java community in the past.[2]
For the model–view–viewmodel pattern, the data transfer object can be referred to as the viewmodel.[4][dubious – discuss]
References
[edit]- ^ a b MSDN (2010). Data Transfer Object. Microsoft MSDN Library. Retrieved from https://msdn.microsoft.com/en-us/library/ms978717.aspx.
- ^ a b c d Fowler, Martin (2010). Data Transfer Object. Patterns of Enterprise Application Architecture. Retrieved from http://martinfowler.com/eaaCatalog/dataTransferObject.html.
- ^ LocalDTO. Retrieved from http://martinfowler.com/bliki/LocalDTO.html.
- ^ Microsoft Learn (3 January 2024). "Tutorial: Create a web API with ASP.NET Core".
External links
[edit]Data transfer object
View on GrokipediaFundamentals
Definition
A data transfer object (DTO) is a simple object that carries data between processes or layers in a software application, typically consisting of fields for storing data along with basic accessor and mutator methods.[1][4] This design pattern encapsulates related data into a single unit to facilitate efficient transfer, particularly in distributed or tiered architectures where direct access to domain objects may be impractical.[1] The primary motivation for using a DTO is to reduce the number of method calls or remote invocations required to retrieve or send data, thereby minimizing communication overhead such as network roundtrips.[1][4] By bundling multiple data elements into one object, it avoids the limitations of passing numerous parameters or handling single-return-value constraints in remote interfaces.[1] DTOs must support serialization to enable transmission across process boundaries, such as networks or isolated execution environments, ensuring the data can be converted to a transmittable format like bytes or XML.[1][4] They are explicitly designed as data holders without incorporating any business logic, such as validation, computation, or behavioral methods, to maintain separation of concerns and keep the object lightweight.[1][4]Characteristics
Data transfer objects (DTOs) are designed as plain data carriers, typically consisting of public or private fields that hold simple data types or references to other DTOs, accompanied by standard getter and setter methods for access.[2] These structures avoid complex inheritance hierarchies or intricate relationships, maintaining a flat composition to facilitate straightforward serialization and deserialization across processes.[1] This simplicity ensures that DTOs serve solely as containers without embedding domain-specific logic or dependencies.[4] In terms of behavior, DTOs exhibit minimal functionality, restricted to essential operations such as serialization for network transfer, along with overridden methods like toString(), equals(), and hashCode() to support basic object identity and representation.[2] They deliberately omit any business methods or validation logic, preserving their role as passive data vessels that do not influence or react to the transferred information.[1] While DTOs can be mutable through the inclusion of setters, immutability is often preferred in their design to safeguard against unintended modifications during transit, achieved by providing only getters and constructor-based initialization.[4] Immutable DTOs enhance thread safety and reduce the risk of side effects in multi-threaded or distributed environments, making them a recommended variant where data integrity is paramount.[4] To promote transfer efficiency, DTOs are engineered to be lightweight, frequently involving the flattening of nested object structures into primitive fields or arrays, thereby minimizing the overall payload size and serialization overhead.[2] This optimization prioritizes the inclusion of only essential data relevant to the transfer context, excluding extraneous attributes to streamline communication between layers or systems.[1]Historical Context
Origins
The Data Transfer Object (DTO) pattern originated in the late 1990s amid the rise of distributed enterprise applications in Java, particularly within the Enterprise JavaBeans (EJB) framework, which Sun Microsystems released in version 1.0 in 1998.[5] Early adopters encountered significant performance challenges in these environments, as distributed systems relied on remote communication protocols that made fine-grained data access inefficient.[4] In EJB contexts, the pattern was initially termed "Transfer Object" in Sun Microsystems documentation, serving as a mechanism to encapsulate multiple data elements into a single, serializable entity for transfer between application clients and enterprise beans.[4] This approach was motivated by the high cost of network round-trips in systems using Java Remote Method Invocation (RMI) or Common Object Request Broker Architecture (CORBA), where retrieving individual attributes via separate remote calls could lead to excessive latency and overhead.[4] By batching data into one object, Transfer Objects minimized the number of invocations, thereby optimizing data exchange in early Java distributed applications from the late 1990s to early 2000s.[4] The pattern gained broader recognition and formalization when Martin Fowler introduced it as the "Data Transfer Object" in his 2002 book Patterns of Enterprise Application Architecture.[1] Fowler described DTOs as lightweight objects designed to carry aggregated data across process boundaries, specifically to enhance the efficiency of remote interfaces in enterprise architectures.[1] This documentation built on the practical needs observed in EJB and similar frameworks, establishing the pattern as a key solution for mitigating the inefficiencies of distributed object communication.[1]Development and Adoption
In 2004, Martin Fowler refined his earlier description of the Data Transfer Object (DTO) pattern by introducing the concept of "Local DTOs" in a bliki post, explicitly warning developers against using DTOs in non-remote, local contexts within the same process or tier, as this could introduce unnecessary complexity without the performance benefits intended for distributed systems.[6] He emphasized that DTOs should remain confined to scenarios involving expensive remote calls, such as those across network boundaries, to avoid pattern misuse that dilutes their original purpose of optimizing data transfer efficiency.[6] During the 2000s, the DTO pattern gained widespread adoption in web services, particularly as structured payloads in SOAP-based APIs, where XML-serializable DTOs served as data contracts to encapsulate and exchange information between distributed components.[1] As RESTful APIs proliferated following Roy Fielding's 2000 dissertation, DTOs adapted to JSON formats, becoming standard for representing request and response data in lightweight, HTTP-based services that emphasized simplicity and stateless interactions.[7] Major frameworks integrated native support for DTOs to streamline their use in enterprise applications. The Spring Framework, released in its 1.0 version in 2004, incorporated DTOs into its MVC and web services modules, enabling automatic mapping and serialization for Java-based APIs.[2] Similarly, Microsoft's Windows Communication Foundation (WCF), introduced in 2006 as part of .NET Framework 3.0, utilized DataContracts—functionally equivalent to DTOs—for defining serializable message structures in SOAP and REST endpoints. In the Node.js ecosystem, Express.js frameworks adopted DTOs for microservices architecture during the 2010s, often employing libraries like class-validator to enforce data shapes in TypeScript-based REST APIs.[8] As of 2025, DTOs maintain strong relevance in cloud-native applications, serving as efficient data carriers in serverless environments like AWS Lambda, where they facilitate JSON payloads between functions and external services.[9] In Kubernetes-orchestrated systems, DTOs support inter-pod communication via REST or emerging protocols. Adaptations include GraphQL's schema-defined input and output types, which function analogously to DTOs for flexible client-driven queries, and gRPC's Protocol Buffer messages, which provide typed, binary-serialized DTO equivalents for high-performance, polyglot microservices.[7]Applications and Use Cases
In Distributed Systems
In distributed systems, Data Transfer Objects (DTOs) play a crucial role in client-server architectures by bundling related data from multiple queries into a single object, thereby minimizing the number of API calls required. For instance, a server can assemble a comprehensive DTO containing a user's profile details alongside their order history, allowing the client to retrieve all necessary information in one remote invocation rather than issuing separate requests for each component. This approach, often paired with a Remote Facade pattern, reduces the overhead of network roundtrips in environments like RESTful web services or microservices ecosystems.[1][2] DTOs are commonly serialized into formats such as JSON, XML, or Protocol Buffers to facilitate efficient transmission across process boundaries in distributed setups. JSON remains prevalent in RESTful APIs due to its human-readable structure and broad language support, while Protocol Buffers offer compact binary encoding for high-performance scenarios, resulting in smaller payloads than JSON in bandwidth-constrained networks. In microservices, these serialized DTOs serve as standardized contracts between services, enabling seamless data exchange without exposing internal domain models.[1][2][10] Regarding performance in remote calls, DTOs optimize latency by consolidating data transfers, which is particularly beneficial in systems involving web APIs or message queues like Apache Kafka. By encapsulating multiple data elements into one payload, DTOs can decrease the total number of invocations, potentially cutting response times in high-latency networks; for example, in Kafka-based event streaming, a single DTO payload can carry aggregated event data, avoiding fragmented messages that would increase processing overhead. This bundling strategy enhances throughput in distributed environments where each remote method call incurs significant serialization and deserialization costs.[1][2][11] From a security perspective, DTOs act as explicit contracts that limit data exposure in distributed APIs, ensuring only essential fields are transmitted and sensitive information—such as full addresses or internal identifiers—is omitted. This controlled serialization prevents excessive data leaks and helps comply with privacy regulations by filtering domain entities before they cross network boundaries. In client-server interactions, using DTOs thus mitigates risks associated with over-fetching, where unfiltered responses might inadvertently reveal confidential details.[12]In Layered Architectures
In layered architectures, Data Transfer Objects (DTOs) serve as intermediaries to transfer data across boundaries such as the domain or service layers to the presentation layer, ensuring that internal domain models remain unexposed and preserving separation of concerns. In Model-View-Controller (MVC) and Model-View-ViewModel (MVVM) patterns, DTOs facilitate the flow of simplified, presentation-friendly data from business logic to the user interface, often through mapping mechanisms that convert complex entities into flat structures suitable for rendering. For instance, in MVVM, DTOs act as model components that encapsulate raw data without behavior, allowing the ViewModel to transform it further for binding to views while avoiding direct dependencies on domain entities.[13][14] An important application of DTOs in layered systems is the anti-corruption layer (ACL), which uses them to shield core business logic from incompatible external or legacy components, such as third-party APIs or outdated databases. By mapping incoming data from external schemas—often in formats like XML derived from XSDs—into DTOs, the ACL translates it into domain-compatible forms before integration, preventing pollution of the internal model. Tools like the Dozer framework automate bidirectional mapping between DTOs and domain objects, as seen in loan processing applications where a single FundingRequestDTO aggregates disparate external data into structured entities like Loan and Borrower without exposing the core logic to external changes.[15] DTOs also support efficient data handling in presentation scenarios by enabling aggregation and batching for UI rendering or reporting, thus avoiding the direct exposure of database entities. In these cases, service layers assemble multiple related data points into composite DTOs tailored for batch operations, such as dashboard views or summary reports, reducing the need for multiple layer traversals and maintaining encapsulation. This approach ensures that the presentation layer receives only necessary, denormalized data payloads optimized for display logic.[15] To manage evolution in layered dependencies, DTOs function as stable contracts between layers, accommodating schema changes without disrupting upstream or downstream components. For example, adding a new property to a domain entity requires updates only within the mapping to the DTO, leaving the presentation layer's interface unchanged and allowing independent versioning of business logic. This isolation promotes resilience, as alterations in one layer—such as enhanced validation in the service tier—do not propagate risks to others.[14]Related Design Patterns
Comparison with Value Objects
Data transfer objects (DTOs) and value objects (VOs) both serve to encapsulate data but differ fundamentally in purpose, design, and application. DTOs are designed primarily for efficient data transport across layers or processes, often prioritizing simplicity and serialization over behavioral semantics. In contrast, VOs, a concept from domain-driven design (DDD), represent domain concepts that lack identity and emphasize immutability to ensure consistency in business logic.[16][17] A key distinction lies in identity and equality. VOs are immutable objects whose equality is determined by the values of their attributes rather than reference or unique identity, allowing interchangeable instances with identical content—such as twoAddress objects with the same street, city, and postal code being considered equal. DTOs, however, typically lack intrinsic identity and may be mutable, with equality often based on object reference or explicit implementation; they do not inherently enforce value-based equality since their role is transient data carriage without domain semantics.[16][17]
In terms of scope, VOs are integral to domain modeling, encapsulating concepts like money, dates, or coordinates that support business rules within the core application logic. For instance, an Address VO might include validation methods to ensure postal code formats align with domain requirements. DTOs, by comparison, are transient structures used solely for data transfer, such as serializing user profile data from a service layer to a client, without embedding domain behavior.[16][17]
The lifecycle of these objects further highlights their divergence. VOs persist within the domain layer, maintaining their state and supporting ongoing operations as part of the application's business model. DTOs, however, are created for specific transfer operations and discarded afterward, minimizing overhead in distributed environments.[16]
This distinction has led to confusion, particularly in Java contexts where the Sun Microsystems community initially used "value object" interchangeably with DTO to describe serializable data carriers for enterprise JavaBeans. Martin Fowler noted this overlap but clarified that DTOs are specifically for transfer efficiency, while true VOs carry domain-specific behavior, urging separation to avoid conflating infrastructural patterns with domain concepts.[1]
Comparison with Domain Models
Data transfer objects (DTOs) differ fundamentally from domain models in their purpose and structure, with DTOs serving as simple data carriers optimized for transfer across layers or processes, while domain models encapsulate the core business concepts with integrated behavior.[1] In domain-driven design (DDD), domain models, particularly entities, include methods for validation, business operations, and state management to enforce invariants and reflect real-world behaviors, whereas DTOs contain no such logic and consist solely of data fields to minimize overhead during serialization and transmission.[18][19] Regarding persistence, domain models are designed to map directly to database schemas using object-relational mapping (ORM) tools, allowing them to maintain identity and relationships over time while handling storage concerns within the domain layer.[18] DTOs, by contrast, deliberately avoid persistence-related annotations or mechanisms, focusing instead on transient data exchange to decouple the domain from infrastructure details like databases.[1] A key distinction arises in their alignment with model richness: domain models aim for a "rich" structure where behavior and data are cohesively bound to support complex business rules, as advocated in DDD to avoid procedural pitfalls.[19] DTOs, however, embody an anemic structure by design—lacking methods or invariants—which makes them unsuitable for hosting core domain logic, potentially leading to anti-patterns if domain entities are similarly stripped of behavior in favor of transfer-friendly forms.[19] To bridge these paradigms, applications typically employ mapping tools or assemblers to convert between domain models and DTOs, ensuring data flows without exposing internal domain behaviors externally; for example, libraries like AutoMapper automate this projection in .NET environments by configuring conventions for object-to-object transformations.[1]Implementation
Design Principles
Data Transfer Objects (DTOs) are designed with a preference for flat structures to enhance simplicity in serialization and deserialization processes, thereby reducing overall complexity in data exchange across layers or systems.[20][2] This approach avoids deep nesting of objects, which can complicate parsing and increase the risk of serialization errors, promoting a straightforward representation that aligns with their role as lightweight carriers of data.[20] When selecting fields for a DTO, only the data essential to the specific transfer context should be included, minimizing unnecessary information that could inflate payload sizes or expose sensitive details.[2][20] This selective inclusion not only optimizes bandwidth usage but also shrinks the potential attack surface by excluding extraneous attributes, such as internal identifiers or computed values not required by the recipient.[2] Immutability is a recommended principle for DTOs where practical, achieved through mechanisms like final fields or builder patterns to lock the object after construction and prevent modifications during transit.[2][20] This ensures data integrity and thread safety, as the object's state remains consistent from creation to consumption, avoiding unintended alterations that could lead to inconsistencies in distributed environments.[20] For handling evolution in APIs or systems, versioning strategies in DTO design typically involve incorporating a version field within the object or creating distinct DTO classes for each version to support backward compatibility.[20] The version field approach allows clients to indicate compatibility levels during serialization, while separate DTOs enable isolated changes without disrupting existing integrations, facilitating maintainable updates over time.[20]Examples in Programming Languages
In Java, Data Transfer Objects are commonly implemented as plain classes with Lombok annotations to reduce boilerplate code for getters, setters, and constructors, while Jackson handles JSON serialization for API responses. The following example defines aUserDTO class using Lombok's @[Data](/page/Data) annotation, which generates the necessary accessors, and Jackson's @[JsonProperty](/page/JSON) for field mapping:
import com.fasterxml.jackson.annotation.[JsonProperty](/page/JSON);
import lombok.[Data](/page/Data);
@Data
public class UserDTO {
@JsonProperty("id")
private Long id;
@JsonProperty("name")
private [String](/page/String) name;
@JsonProperty("email")
private [String](/page/String) email;
}
import com.fasterxml.jackson.annotation.[JsonProperty](/page/JSON);
import lombok.[Data](/page/Data);
@Data
public class UserDTO {
@JsonProperty("id")
private Long id;
@JsonProperty("name")
private [String](/page/String) name;
@JsonProperty("email")
private [String](/page/String) email;
}
ObjectMapper for transfer between service layers or to clients.
In C#, DTOs are often defined as classes with [DataContract] and [DataMember] attributes to enable serialization in WCF services, ensuring controlled data exposure.[21]
A typical example is a UserDto class configured for data contract serialization:
using System.Runtime.Serialization;
[DataContract]
public class UserDto
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
}
using System.Runtime.Serialization;
[DataContract]
public class UserDto
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
}
DataContractJsonSerializer in WCF contexts.[21]
In Python, Pydantic models serve as DTOs for API responses, providing type validation and automatic serialization to JSON, commonly used in frameworks like FastAPI.[22]
An example UserDTO model using Pydantic's BaseModel:
from pydantic import BaseModel
class UserDTO(BaseModel):
id: int
name: str
email: str
from pydantic import BaseModel
class UserDTO(BaseModel):
id: int
name: str
email: str
User entity to UserDTO:
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
@Mapper
public interface UserMapper {
UserDTO toDto(User user);
}
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
@Mapper
public interface UserMapper {
UserDTO toDto(User user);
}
using AutoMapper;
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<User, UserDto>();
});
IMapper mapper = config.CreateMapper();
var userDto = mapper.Map<UserDto>(domainUser);
using AutoMapper;
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<User, UserDto>();
});
IMapper mapper = config.CreateMapper();
var userDto = mapper.Map<UserDto>(domainUser);
