# Data transfer object (DTO)

Data Transfer Object Design Pattern е често използван шаблон за проектиране. Основно се използва за предаване на данни с множество атрибути в една заявка от клиент към сървър, за да се избегнат множество повиквания към отдалечения сървър.

Предимство на използването на DTO в RESTful API, написани на Java (и със Spring Boot), е че те могат да помогнат да се скрият имплементационните детайли на обектите (JPA entities). Разкриването на тези обекти чрез крайни точки може да се превърне в проблем със сигурността, ако не боравим внимателно с това какви свойства могат да бъдат променяни и чрез какви операции.

<figure><img src="https://3165743208-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MUbVVR-jiMUx7iVRyw6%2Fuploads%2FPFTYC28gvr7n8CJlcc4U%2Fimage.png?alt=media&#x26;token=12942a1c-f834-4ac6-8c16-0b22449df68f" alt=""><figcaption></figcaption></figure>

ModelMapper e библиотека, която се използва за преобразуване на entity обект в DTO и обратно.

Стъпки за реализация:

1. Добавяме библиотеката ModelMapper

```xml
<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.1.1</version>
</dependency>
```

За автоматичното конфигуриране на bean можете да предприемете една от двете стъпки:

* в Main класа добавете следния метод, анотиран с @Bean:

```java
@Bean
public ModelMapper modelMapper() {
	return new ModelMapper();
}
```

* или създайте клас-наследник на ModelMapper, анотиран с @Component

```java
@Component
public class CustomMapper extends ModelMapper {
}
```

2. Създаваме entity клас:

<pre class="language-java"><code class="lang-java">@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class User {

<strong>        private int id;
</strong>   	private String name;
    	private String email;
    	private String password;
}
</code></pre>

3. Създаваме DTO клас:

<pre class="language-java"><code class="lang-java">@Setter
@Getter
@NoArgsConstructor
public class UserDto {
    private int id;
    private String name;   	
<strong>    private String email;
</strong>}

</code></pre>

**UserService.java**

```java
public interface UserService {  
 
    public User createUser(UserDto userDto);
    public UserDto getUser(int userId);
}
```

**UserServiceImpl.java**

<pre class="language-java"><code class="lang-java">@Service
public class UserServiceImpl implements UserService {
  
    private UserRepository userRepository;
    private ModelMapper modelMapper;

	public UserServiceImpl(UserRepository userRepository, 
	                       ModelMapper modelMapper){
	this.userRepository = userRepository;
	this. modelMapper = modelMapper;
<strong>    }
</strong>      
    @Override
    public User createUser(UserDto userDto) {
	Use user = modelMapper.map(userDto, User.class);
        User userSavedToDB = userRepository.save(user);
	UserDto userResponse = modelMapper.map(userSavedToDB, UserDto.class);
        return userResponse;
    }
  
    // update it with UserDto
    @Override
    public UserDto getUser(int userId) {
        User user = userRepository.findById(userId).get();
        UserDto userDto = modelMapper.map(user, UserDto.class);
        return userDto;
    }
}
</code></pre>

**UserController.java**

```java
@RestController
@RequestMapping("/api/user")
public class UserController {
      
    private UserServiceImpl userServiceImpl;

    public UserController(UserServiceImpl) {
        this.userServiceImpl = userServiceImpl;
    }
      
    @PostMapping("/create")
    public ResponseEntity<UserDto> createUser(@RequestBody UserDto userDto){
        UserDto userCreated = this.userServiceImpl.createUser(userDto);
        return new ResponseEntity<UserDto>(userCreated, HttpStatus.CREATED);
    }
      
    @GetMapping("/get/{id}")
    public ResponseEntity<UserDto> getUser(@PathVariable("id") int userId){
        UserDto userDto = this.userServiceImpl.getUser(userId);
        return new ResponseEntity<UserDto>(userDto, HttpStatus.OK);
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://programmingfundamental.gitbook.io/programmingwithjava/internet-tekhnologii-2023/laboratorno-uprazhnenie-8/data-transfer-object-dto.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
