Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Projeto] Diferenças na implementação

Olá,

Sei que sempre haverão diferenças na implementação de códigos, entretanto neste Endpoint de Gêneros acabei não escrevendo o "método" RequestToEntity e não sei até onde isto poderia prejudicar a segurança do código ou está em desacordo com as boas práticas.

Poderiam esclarecer esta dúvida e fazer comentários de melhoria no meu código por favor.

Muito obrigado.

using Microsoft.AspNetCore.Mvc;
using ScreenSound.API.Requests;
using ScreenSound.API.Response;
using ScreenSound.Banco;
using ScreenSound.Modelos;
using ScreenSound.Shared.Modelos.Modelos;

namespace ScreenSound.API.Endpoints;

public static class GenerosExtensions
{
    public static void AddEndPointGeneros (this WebApplication app)
    {
        #region Endpoint Genero
        app.MapGet("/Generos", ([FromServices] DAL<Genero> dal) => {
            var listaGeneros = EntityListToResponseList(dal.Listar());
            return Results.Ok(listaGeneros);
        });
        app.MapGet("/Generos/{nome}", ([FromServices] DAL<Genero> dal, string nome) => {
            var listaGeneros = EntityListToResponseList(dal.Listar());
            var genero = listaGeneros.Where(a => a.Nome.ToUpper().Equals(nome.ToUpper()));
            if (genero is null)
            {
                return Results.NotFound("Gênero não encontrado.");
            }
            return Results.Ok(genero);
        });
        app.MapPost("/Generos", ([FromServices] DAL<Genero> dal, [FromBody] GeneroRequest generoRequest) =>
        {
            var genero = new Genero(generoRequest.Nome)
            {
                Descricao = generoRequest.Descricao
            };
            dal.Adicionar(genero);
            return Results.Created();
        });
        app.MapDelete("/Generos", ([FromServices] DAL<Genero> dal, int id) =>
        {
            var genero = dal.RecuperarPor(g => g.Id.Equals(id));
            if (genero is null)
            {
                return Results.NotFound("Gênero não encontrado.");
            }
            dal.Deletar(genero);
            return Results.NoContent();
        });
        #endregion
    }
    private static ICollection<GeneroResponse> EntityListToResponseList(IEnumerable<Genero> listaDeGeneros)
    {
        return listaDeGeneros.Select(g => EntityToResponse(g)).ToList();
    }

    private static GeneroResponse EntityToResponse(Genero genero)
    {
        return new GeneroResponse(genero.Id, genero.Nome!, genero.Descricao);
    }
}
1 resposta
solução!

Olá, Pedro!

Vamos lá! Primeiro, parabéns pelo esforço e pela implementação dos endpoints. Seu código está bem organizado e funcional. Agora, vamos abordar a questão do método RequestToEntity e algumas melhorias que podem ser feitas.

Método RequestToEntity

O método RequestToEntity é uma boa prática para converter objetos de request (DTOs) em entidades do domínio. Isso ajuda a manter o código mais limpo e separado, facilitando a manutenção e a segurança. No seu caso, você está criando a entidade Genero diretamente no endpoint MapPost, o que pode ser melhorado.

Vamos adicionar o método RequestToEntity:

private static Genero RequestToEntity(GeneroRequest generoRequest)
{
    return new Genero(generoRequest.Nome)
    {
        Descricao = generoRequest.Descricao
    };
}

E modificar o endpoint MapPost para utilizá-lo:

app.MapPost("/Generos", ([FromServices] DAL<Genero> dal, [FromBody] GeneroRequest generoRequest) =>
{
    var genero = RequestToEntity(generoRequest);
    dal.Adicionar(genero);
    return Results.Created();
});

Melhorias Adicionais

  1. Validação de Dados: É sempre bom validar os dados recebidos no request para garantir que eles estão no formato esperado e evitar problemas de segurança.

  2. Tratamento de Exceções: Adicionar um middleware global de tratamento de exceções pode ajudar a capturar e logar erros inesperados, retornando respostas adequadas ao cliente.

  3. Uso de Async/Await: Utilizar métodos assíncronos (async/await) pode melhorar a performance da aplicação, especialmente em operações de I/O como acesso ao banco de dados.

Aqui está uma versão aprimorada do seu código com essas melhorias:

using Microsoft.AspNetCore.Mvc;
using ScreenSound.API.Requests;
using ScreenSound.API.Response;
using ScreenSound.Banco;
using ScreenSound.Modelos;
using ScreenSound.Shared.Modelos.Modelos;

namespace ScreenSound.API.Endpoints;

public static class GenerosExtensions
{
    public static void AddEndPointGeneros(this WebApplication app)
    {
        #region Endpoint Genero
        app.MapGet("/Generos", async ([FromServices] DAL<Genero> dal) => {
            var listaGeneros = await dal.ListarAsync();
            var response = EntityListToResponseList(listaGeneros);
            return Results.Ok(response);
        });

        app.MapGet("/Generos/{nome}", async ([FromServices] DAL<Genero> dal, string nome) => {
            var listaGeneros = await dal.ListarAsync();
            var genero = listaGeneros.FirstOrDefault(a => a.Nome.ToUpper().Equals(nome.ToUpper()));
            if (genero is null)
            {
                return Results.NotFound("Gênero não encontrado.");
            }
            return Results.Ok(EntityToResponse(genero));
        });

        app.MapPost("/Generos", async ([FromServices] DAL<Genero> dal, [FromBody] GeneroRequest generoRequest) =>
        {
            if (string.IsNullOrWhiteSpace(generoRequest.Nome))
            {
                return Results.BadRequest("Nome do gênero é obrigatório.");
            }

            var genero = RequestToEntity(generoRequest);
            await dal.AdicionarAsync(genero);
            return Results.Created($"/Generos/{genero.Id}", EntityToResponse(genero));
        });

        app.MapDelete("/Generos/{id}", async ([FromServices] DAL<Genero> dal, int id) =>
        {
            var genero = await dal.RecuperarPorAsync(g => g.Id == id);
            if (genero is null)
            {
                return Results.NotFound("Gênero não encontrado.");
            }
            await dal.DeletarAsync(genero);
            return Results.NoContent();
        });
        #endregion
    }

    private static Genero RequestToEntity(GeneroRequest generoRequest)
    {
        return new Genero(generoRequest.Nome)
        {
            Descricao = generoRequest.Descricao
        };
    }

    private static ICollection<GeneroResponse> EntityListToResponseList(IEnumerable<Genero> listaDeGeneros)
    {
        return listaDeGeneros.Select(g => EntityToResponse(g)).ToList();
    }

    private static GeneroResponse EntityToResponse(Genero genero)
    {
        return new GeneroResponse(genero.Id, genero.Nome!, genero.Descricao);
    }
}

Espero ter ajudado e bons estudos!