DEV Community

Yuri Peixinho
Yuri Peixinho

Posted on

Utilização de DTOs

Em um breve resumo, podemos dizer que o DTO um objeto que define como os dados serão enviados na rede. Apenas exibindo e expondo as informações necessárias.

Existem duas formas de fazer conversões de um DTO, sendo a primeira forma o mapeamento manual, que utiliza a instância do DTO e fornece seus valores manualmente para o objeto. A segunda forma é utilizando a biblioteca AutoMapper que manipula essas conversões automaticamente. Não existe uma abordagem melhor do que a outra, apenas a que se adeque a necessidade do projeto.

Em uma aplicação .NET com EF Core é comum existir o Modelo de Domínio, que busca definir os mapamento das Entidades e traduzi-las para modelo de dados SQL.

Então, após nossa ORM traduzir essas entidades para classes, essas classes serão usadas representar a entrada e saida de dados em nossos endpoints. Veja um exemplo:

  [HttpPost]
  public IActionResult CriarProduto**(Produto produto)**
  {
          [...]
            var ProdutoCriado = _repository.CriarProduto(**categoria**)
            [...]
  }
Enter fullscreen mode Exit fullscreen mode

No entanto, não é uma boa prática expor essas entidades em nossos retornos de endpoints por vários fatores, segurança, perfomance, flexibilidade, complexibilidade.

Segurança

Ao expor todo modelo de dados de uma classe vamos fornece ao cliente todas as informações referente a ela. Alguns exemplos seriam dados sensíveis, como senhas, chaves primárias, dados de desempenho e até dados de auditoria (registro data e hora, deleção lógica e atividades interna da aplicação que não são relevantes para o usuário final).

Perfomance

Transmitir grandes volumes de dados desnecessários por meio da rede pode diminuir o desempenho da aplicação.

Flexibilidade

Expor nossos modelos diminuir a flexibilidade da nossa aplicação. Já que alterando a classe da nossa Entidade vai afetar diretamente todos os endpoints que utilizam.

Complexibilidade

Clientes que consomem nossa API terão que se adpatar a um grande e desnecessário volume de informações, o que pode desagradá-lo e executar uma integração mais propensa a erros.

Vamos então imaginar que temos uma Entidade Livro e a classe que o representa é:

public class Livro 
{
        public int Id { get; set; }
        public string Titulo { get; set; }
        public int Ano { get; set; }
        public decimal Preco { get; set; }
        public string NomeDoAutor { get; set; }
        public string Genero { get; set; }
        public string SenhaDeAcesso { get; set; }
    public DateTime UltimaAtualizacao { get; set; } 
}
Enter fullscreen mode Exit fullscreen mode

Observando essa classe Modelo, podemos ver informações três graus de informações, sendo sensíveis como **SenhaDeAcesso* e UltimaAtualizacao , informações essenciais e informações não essenciais.*

Em nosso exemplo vamos criar duas classes DTO. A primeira exibirá apenas informações essenciais, enquanto a segunda detalhada.

public class LivroDto
{
    public int Id { get; set; }
    public string Titulo { get; set; }
    public string NomeDoAutor { get; set; }
}

public class LivroDetalhesDto
{
    public int Id { get; set; }
    public string Titulo { get; set; }
    public int Ano { get; set; }
    public decimal Preco{ get; set; }
    public string NomeDoAutor { get; set; }
    public string Genero { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Definindo essas classes, podemos então fazer uso em nossos métodos para que retornem o DTOs.

Em seguida vamos para o Controller de nossa aplicação para fazermos os ajustes.

[HttpGet]
public IEnumerable**<LivroDTO>** GetLivros()
{
    var livrosDTO = _context.Livros.Select(livro => **new LivroDTO**
    {
        Id = livro.Id,
        Título = livro.Título,
        Ano = livro.Ano,
        Preço = livro.Preço,
        NomeDoAutor = livro.NomeDoAutor,
        Gênero = livro.Gênero
    }).ToList();

    return **livrosDTO**;
}
Enter fullscreen mode Exit fullscreen mode

Explicando o código

  • O retorno do nosso método será que indica que vamos retornar um objeto deLivroDTO conforme desenvolvemos anteriormente.
  • A varável livrosDTO acessa o contexto que representa o banco de dados para fazer a seleção de todos os livros para um objeto LivroDTO.
  • Por fim retornamos uma lista de DTOs que criamos para representar os livros durante uma requisição HTTP.

É reconhecido como mapeamento manual pois temos que passar os valores do contexto do nosso banco para o DTO manualmente por meio da instanciação da própria classe LivrosDTO.

Top comments (0)