Mastodon

How I use DTOs

Because I recently read about this pattern, here are some words about how I use DTOs, Data Transition Objects. DTOs are used to transport data, for example from server to client and vice versa. Let’s have a look at the case where you want to load data from a server to represent it in a client. Often, the user interface represents data from different entities, like having an administration interface where persons and their permissions are shown. Because the entity person and the entity permission are involved, it’s best to have an DTO that wrapps the needed data. So in this case, the DTO is kind of a summary of the needed information.

public class Person {
 
    private Long id;
    private String name;
 
    // Dozer doesn't understand java.time.Instant ... too bad.
    private Date creationDate;
    private Date changeDate;
 
    // getter / setter
}

and

public class Permission {
 
    private Long id;
    private Person person;
 
    private String text;
 
    // getter / setter
}

is transported as

public class PersonDTO {
 
    private Long id;
 
    private String name;
 
    private List<String> permissions;
 
    // Dozer doesn't understand java.time.Instant ... too bad.
    private Date creationDate;
    private Date changeDate;
 
    // getter / setter
}

DTOs are also used for getting data from the client to the server so it can be persisted. I often see that people reuse their DTOs send from the server for getting data back there. I think it’s better to use an UpdateDTO like this:

public class PersonUpdateDTO {
 
    private Long id;
 
    private String name;
 
    private List<String> permissions;
 
    // getter / setter
}

This looks pretty much like the DTO the data came in from the server, but it just contains the attributes that have to be send to the server. In my example, the DTO contains meta-information like when the person’s permission was changed the last time. Because this attribute is set by the database, it doesn’t need to be send from the client to the server. Often, these attributes are set to null which results in code like

persistService.save(new PersonDTO("The Dude", null, null));

because the time of creation and update is set to null. Even worse is this:

persistService.save(new PersonDTO("The Dude", new Date(), new Date()));

because the time set to this object will be overriden by the server and hence doesn’t have any purpose. This is the solution I prefer:

persistService.save(new PersonUpdateDTO("The Dude"));

I’m loading everything I need to display in one request, so there are a lot of attributes to set in a DTO. To avoid code like

PersonDTO dto = new PersonDTO(person.getName(), person.getSurname(), person.getCreationDate(). person.getUpdateDate());

I use Dozer so the code looks like this:

PersonDTO personDTO = new DozerBeanMapper().map(person, PersonDTO.class);

Recently I had the idea to rename our PersonDTO to PersonTO like in “Person Transfer Object” (note the missing “D”) because for me it was clear that we want to transport data. However, DTO is a pattern by Martin Fowler. That is the reason why you want your DTOs to be DTOs. ;)

TL;DR:

Use DTOs instead of sending your entities. Use different objects for loading and writing: DTO and UpdateDTO. Use Dozer for mapping. Name them “DTO”.

(Photo: https://en.wikipedia.org/wiki/Transport_in_Mali#/media/File:Mali_-_local_transport.jpg By Ferdinand Reus from Arnhem, Holland - Flickr, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=3249038)