Why use DTOs (Data Transfer Objects)?

Data Transfer Objects

Should you really use DTOs (Data Transfer Objects)? Seem like a lot of work mapping your database entities to another object? Why Bother? The simple answer is coupling.

Data Transfer Objects

First, what are DTOs? When people refer to Data Transfer Objects, what they mean are objects that represent data structures that generally do not contain any business logic or behavior. If they do contain behavior, it’s generally trivial.

Data Transfer Objects are often used to be serialized by the producer and then deserialized by the consumer. Often times these consumers may live in another process being used by an entirely different language and/or platform.

YouTube

I’ve recorded a short video explaining this with some sample code. Check out the video and make sure to subscribe to my YouTube Channel.

Crossing Boundaries

The most common example of this is creating an HTTP API using ASP.NET Core that returns an object from its Controller actions that are ultimately serialized to JSON. The consumer is oftentimes JavaScript that uses those JSON responses in displaying the browser using a Component or SPA Framework.

Internals

If you’re not using DTOs, then you’re likely exposing internal data structures.

The biggest culprit of this is simple TODO demo applications that expose the database entities directly. Meaning they output a serialized list of TODOs to the javascript frontend. And when you want to create a new record, they often times take the TODO object to insert directly into the database. This is leaking internals.

This is my biggest complaint with simple demo applications are they often don’t implement or follow some practices, because rightly so, they aren’t applicable to a simple TODO application. However, people take the example of a simple TODO and use the same patterns into a much large application.

The problem is when internal data objects are serialized and consumed by a client you either down own or cannot change easily. Or, which happens more often, the application itself gets very large.

Contracts

The moment you want change internal data objects, you now have to update the clients.

Take this simple example of a Customer that is an internal data structure we use through the system and likely use to persist using an ORM.

If we are serializing this structure and clients are consuming this, if we change this structure, we’re likely going to break out clients.

This change would require a change to all of our clients. We could easily make this change in our own codebase and have all our own usages be correct, but we would be breaking all of our decoupled clients that get a serialized representation.

Representation

When creating an HTTP API, it’s all about representations. Most often times clients need a rich representation of a resource, not a just serialized version of a database entity. They often times need related data.

Having your API return rich representations means you must do some level of composition to create an object, not just a database entity, that will get serialized. This is where a DTO comes into play.

I actually don’t often use the term DTO, but rather use the word Representation or ViewModel. The purpose is still the same, it’s a data structure that is a contract between the producer and the consumer. That contract should remain stable (through backwards compatibility) or have a versioning strategy.

Coupling

The reason you want to use DTOs is that you want clients to couple to that contract, not to your internal data structures. This allows you to modify and evolve your internals freely without breaking clients.

Links

Follow @CodeOpinion on Twitter

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Leave a Reply

Your email address will not be published. Required fields are marked *