Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API - DTOs or not? [closed]

People also ask

Should you use DTOs?

A DTO is helpful whenever you need to group values in ad hoc structures for passing data around. From a pure design perspective, DTOs are a solution really close to perfection. DTOs help to further decouple presentation from the service layer and the domain model.

Is using DTO a good practice?

Transfering data using Dtos between "local" services is a good practice but have a huge overhead on your developer team. There is some facts: Clients should not see or interact with Entities ( Daos ). So you always need Dtos for transferig data to/from remote (out of the process).

What are DTOs used for?

Data transfer object (DTO), formerly known as value objects or VO, is a design pattern used to transfer data between software application subsystems. DTOs are often used in conjunction with data access objects to retrieve data from a database.

What does DTO mean in API?

DTO stands for Data Transfer Object. This pattern was created with a very well defined purpose: transfer data to remote interfaces, just like web services. This pattern fits very well in a REST API and DTOs will give you more flexibility in the long run. ... Decouple persistence models from API models.


Why you should use DTOs in your REST API

DTO stands for Data Transfer Object.

This pattern was created with a very well defined purpose: transfer data to remote interfaces, just like web services. This pattern fits very well in a REST API and DTOs will give you more flexibility in the long run.

The models that represent the domain of your application and the models that represent the data handled by your API are (or at least should be) different concerns and should be decoupled from each other. You don’t want to break your API clients when you add, remove or rename a field from the application domain model.

While your service layer operates over the domain/persistence models, your API controllers should operate over a different set of models. As your domain/persistence models evolve to support new business requirements, for example, you may want to create new versions of the API models to support these changes. You also may want to deprecate the old versions of your API as new versions are released. And it’s perfectly possible to achieve when the things are decoupled.


Just to mention a few benefits of exposing DTOs instead of persistence models:

  • Decouple persistence models from API models.

  • DTOs can be tailored to your needs and they are great when exposing only a set of attributes of your persistence entities. You won't need annotations such as @XmlTransient and @JsonIgnore to avoid the serialization of some attributes.

  • By using DTOs, you will avoid a hell of annotations in your persistence entities, that is, your persistence entities won't be bloated with non persistence related annotations.

  • You will have full control over the attributes you are receiving when creating or updating a resource.

  • If you are using Swagger, you can use @ApiModel and @ApiModelProperty annotations to document your API models without messing your persistence entities.

  • You can have different DTOs for each version of your API.

  • You'll have more flexibility when mapping relationships.

  • You can have different DTOs for different media types.

  • Your DTOs can have a list of links for HATEOAS. That's the kind of thing that shouldn't be added to persistence objects. When using Spring HATEOAS, you can make your DTO classes extend RepresentationModel (formerly known as ResourceSupport) or wrap them with EntityModel (formerly known as Resource<T>).

Dealing with the boilerplate code

You won't need to map your persistence entities to DTOs and vice versa mannually. There are many mapping frameworks you can use to do it. For instance, have a look at MapStruct, which is annotation based and works as a Maven Annotation Processor. It works well in both CDI and Spring-based applications.

You also may want to consider Lombok to generate getters, setters, equals(), hashcode() and toString() methods for you.


Related: To give better names to your DTO classes, refer to this answer.


When your API is public and you have to support multiple versions, you have to go with DTOs.

On the other hand, if it's private API and you control both client and server, I tend to skip the DTOs and expose directly domain model.


I tend to use DTOs.

I don't like the drawbacks but it seems that the other options are even worse:

Exposition of domain objects may lead to security issues and data leak. Jackson annotations may seem to solve the problem but it's too easy to make a mistake and expose data which should not to be exposed. When designing a DTO class it's much harder to make such a mistake.

On the other side the drawbacks of DTO approach can be reduced with things like object to object mapping and Lombok for less boilerplate.


As you already stated yourself, this is clearly an opinion related question. I myself am more drawn to the No-DTOs approach, simply because of all the boilerplate code you need.

This is mainly true for the response side of a json/rest api. I even wrote a jackson addon to avoid writing many json views / filters for these cases: https://github.com/Antibrumm/jackson-antpathfilter

On the other hand DTOs are a good thing on the request input side of such APIs. Working directly on entities can be pretty hard taking into account bidirectional relations for example. Also you dont really want to let a caller modify a "creator" attribute for example. So you would need to dissallow certain fields during the mapping of such requests.