How to implement DTOs in Spring boot
Published: 2023-06-03 22:03:39

# How to implement DTOs in Spring boot

## 1.Why

The DTO pattern is powerful to make sure that you are returning safe data to your end user

## 2.Simple Explanation

The ideia is that we use the DTOS to transfer data from the client to our services and from our services to the client, keeping it more concise and making sure that the user does not have access to data eh souldn’t.

We define the data that we want to receive from the client in the CreateClientDTO and the data we will send the client in the ResposeClientDTO

In this example i’ll be using [Lombock](https://projectlombok.org/) just to automatically create some boiler plate for us.

> Client model
> 

```java
@Getter
@Setter
@NoArgsConstructor
@Entity
public class Client {

    public Client(String name, String email, String password) {
        this.name = Objects.requireNonNull(name);
        this.email= Objects.requireNonNull(email);
        this.password = this.encrypt(password);
    }

    private String encrypt(String password) {
        return password;
    }

    @Id()
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;
}
```

For correctly creating our *Client* using a DTO we must have a constructor with no id provided, as this will be automatically created by *@GeneratedValue* method, you will understand more about it later on.

> CreationDTO
> 

```java
@Getter
@AllArgsConstructor
public class CreateClientDTO {
    private String name;
    private String email;
    private String password;
}
```

Here in the *CreateClientDTO* we will have only the variables that we need the client to send us for the user to be correctly created, note that the *id* is not here.

 **

> responseDTO
> 

```java
@Getter
@AllArgsConstructor
public class ResponseClientDTO {
    private Long id;
    private String name;
    private String email;
}
```

And here in the response DTO we will have only the data that we want to send back to our client, note that the *password* is not here.

> Mapper
> 

```java
@Component
public class Mapper {
    public ResponseClientDTO toDto(Client client) {
        Long id = client.getId();
        String name = client.getName();
        String email = client.getEmail();
        return new ResponseClientDTO(id, name, email);
    }

    public Client toClient(CreateClientDTO clientDTO) {
        return new Client(clientDTO.getName(), clientDTO.getEmail(), clientDTO.getPassword());
    }
}
```

The mapper is the class we are gonna use to transform the data that comes from our service to the data that we want to send the user, and vice-versa.

> ClientController
> 

```java
@RestController
@RequestMapping("/client")
public class ClientController {

    private final ClientRepository clientRepository;
    private final Mapper mapper;

    @Autowired
    public ClientController(ClientRepository clientRepository, Mapper mapper) {
        this.clientRepository = clientRepository;
        this.mapper = mapper;
    }

    @GetMapping("/{clientId}")
    public ResponseEntity<ResponseClientDTO> getClient(@PathVariable Long clientId) {
        Optional<Client> client = clientRepository.findById(clientId);

        return client.map(c -> ResponseEntity.ok().body(mapper.toDto(c)))
                .orElseGet(() -> ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<ResponseClientDTO> createClient(@RequestBody CreateClientDTO clientDTO) {
        Client client = mapper.toClient(clientDTO);
        Client createdClient = clientRepository.save(client);

        return ResponseEntity.ok().body(mapper.toDto(createdClient));
    }
}
```

Here in our *ClientController, in our @GetMapping("/{clientId}"),* we are getting the user from the repository using the *findById,* that our client provided, then mapping it to return as a *ResponseEntity* parsing it to the DTO model using our *mapper.*

In the *@PostMapping* we do both, transform the data our client sent as a DTO through the body into a *Client* using *the mapper,* then save it using the *clientRepository* and transform it into the DTO again before sending the response to our client.