This page describes the DTOs we use in LabraCORE to transfer information to and from the core service. We describe what DTOs are and why we use them, what the different types of DTOs are that we are going to use and provide an overview of the currently available DTOs.
What are DTOs
DTO stands for Data Transfer Object. DTOs can be with or without structure. Structureless DTOs can be seen in Javascript: one can create a JSON object at any point with any number of fields and with any types of fields. We use DTOs in a structured fashion, so every object sent over a network to and from LabraCORE is parsed to and serialized from some predetermined format.
In Java Spring, DTOs are simple POJOs. The fields in a DTO class represent the keys of data to be sent and the type of the field can be seen as a contract as to how to parse and serialize data in that DTO.
The different types of DTOs
Within Librador, we distinguish between a couple different types of DTO, corresponding to a couple different actions that can be done within the application.
Create
The Create DTO is used in the body of a POST request that is supposed to create some new database entry. Create DTOs contain a function to convert the DTO into a valid database object called apply. This DTO, like all following DTOs out of the Librador library, uses the ModelMapper library to map POJOs into other POJOs without too much hassle.
Create DTOs enable swift and easily customizable validation on create operations and standardized conversion into a database object that is to be saved.
Patch
The Patch DTO is used in the body of a PATCH request that is supposed to change some value in an existing database entry. Patch DTOs contain a similar function to that found in Create DTOs. The difference is that apply takes, as an argument, the entity that the patch is supposed to be used on. The entity is then modified according using the modifications proposed in the patch DTO.
Patches make heavy use of helper methods to define when a change is actually applied.
We use null
values in Patches to denote that no change should be made to that field. updateNonNull
calls can be used to then update the entity class appropriately.
A Patch should never contain the ID of the entity to be changed, this should always be provided within the request directly through a path variable or query parameter.
Patches are rather complicated and may be quite tricky to use. Take a good look at the section on how to create patch DTOs, examples and the methods within GenericPatch to understand what the methods in Patches can do.
Patch with IDs
PatchWithIds is a special type of Patch DTO that has mostly the same functionality as the original Patch DTO. In addition to the Patch DTO, however, it provides conversion methods for those fields that use an ID DTO instead of a normal DTO or flat data.
View
View DTOs are simple in use, but complicated in their quantity. A view is a way to limit or remodel the information that is transferred back to services from the LabraCORE API. Often, views only provide the same fields as their representing Entity class.
Views are structured in a peculiar way in LabraCORE. A core principal in structuring views is how many recursive steps need to be taken to serialize an entity into a View. For instance, when serializing an Edition that contains a number of Persons, we could take 1 recursive step from the edition class to serialize all Person classes it holds.
When 0 such hops are required, we call the DTO a summary DTO. These summaries are therefore easy to serialize and deserialize and contain the least amount of nested data possible. Anything other than that is either a Layer_n DTO or a Details DTO.