ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor - Parte 6
Neste novo post retomo a série de dicas úteis para o dia a dia de Desenvolvedores ASP.NET Core. Caso ainda não tenha consultado os 5 artigos anteriores ou, até mesmo, gostaria de revê-los acesse os links a seguir:
ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 1
ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 2
ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 3
ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 4
ASP.NET Core: dicas úteis para o dia a dia de um Desenvolvedor — Parte 5
E aproveito este espaço para deixar aqui ainda um convite.
Dia 17/09/2019 (terça) a partir das 21:30 — horário de Brasília — teremos mais uma live no Canal .NET. Desta vez eu (Renato Groffe) apresentarei diversas dicas e truques na utilização de containers Docker e englobando tecnologias como ASP.NET Core, .NET Core, Docker Compose, Kubernetes, SQL Server, MongoDB, Linux, MySQL, NGINX, Postgresql…
Para efetuar a sua inscrição acesse a página do evento no Meetup. A transmissão acontecerá via YouTube, em um link a ser divulgado em breve.
RabbitMQ: evitando processamentos de longa duração em Web Apps
A prática de evitar processamentos de longa duração em aplicações Web pode ser facilmente implementada por meio de tecnologias de mensageria como o RabbitMQ. Soluções deste tipo se baseiam em um pattern conhecido como Fire-and-Forget, com o envio de mensagens para a manipulação posterior em um processo executando à parte de uma Web App.
Já abordei a utilização de RabbitMQ com ASP.NET Core no seguinte artigo (inclui repositório no GitHub):
.NET Core 2.2 + ASP.NET Core 2.2 + RabbitMQ: exemplos utilizando mensageria
O RabbitMQ também foi tema de uma live no Canal .NET neste ano de 2019:
O atributo ApiController: simplificando a codificação de APIs REST
Introduzido no ASP.NET Core 2.1, o atributo ApiController possibilita a implementação de APIs REST com um código mais enxuto e limpo. Isto acontece pelo fato de Controllers configurados com essa estrutura dispensarem:
- O uso do atributo FromBody no parâmetro correspondente ao corpo de uma requisição;
- Verificações no início de Actions a fim de determinar se os dados associados ao corpo da requisição são válidos, com isto acontecendo por meio da propriedade IsValid do objeto ModelState.
A utilização de ApiController já foi apresentada por mim no seguinte artigo:
ASP.NET Core 2.1: simplificando a codificação com o atributo ApiController
Na listagem a seguir temos um exemplo de Controller devidamente ajustado com o atributo ApiController:
Uma versão deste exemplo criada com o ASP.NET Core 2.2 pode ser encontrada no repositório:
Dapper.Contrib: simplificando operações de CRUD com Dapper
Uma alternativa para facilitar a implementação de CRUDs com Dapper é o package Dapper.Contrib. Esta opção dispensa o uso de expressões SQL na implementação de instruções voltadas à manipulação de dados em tabelas com uma estrutura mais simplificada.
O Dapper.Contrib permite a utilização dos seguintes métodos com um objeto de conexão:
T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();
A classe que representa um registro/entidade em uma tabela deverá passar por ajustes:
- Os diversos atributos de configuração esperados pelo Dapper.Contrib se encontram no namespace Dapper.Contrib.Extensions;
- O atributo Table associado à declaração da classe indica a tabela à qual a mesma se refere;
- Já o atributo Key vinculado a uma propriedade indica que o valor representado pela mesma é gerado automaticamente (no caso do SQL Server, campos configurados como IDENTITY representam chaves auto-incremento).
Para campos nos quais o valor da chave primária deve ser informado manualmente será utilizado o atributo ExplicitKey, como indicado na próxima listagem (um exemplo envolvendo um tipo chamado Estado):
Ainda considerando a classe Comentario, na listagem a seguir temos a implementação de ComentariosController (tipo que permitirá a consulta e a inclusão de dados representados por Comentario):
- O método GetAll<T> do Dapper.Contrib retornará todos os registros existentes em GetComentarios;
- Já Get<T> permitirá a consulta a um comentário específico por meio de seu ID na Action Get;
- O método Insert<T> possibilitará o cadastramento de um novo comentário na Action Post;
- Nota-se em ComentariosController a ausência de qualquer instrução SQL graças ao uso do Dapper.Contrib.
Disponibilizei no GitHub 2 exemplos de utilização do Dapper.Contrib:
ASP.NET Core 2.2 + ApiController + Dapper.Contrib + FluentValidation + SQL Server
FluentValidation: maior flexibilidade em validações
E retomando o exemplo da API de comentários abordado na seção sobre Dapper.Contrib, detalharei agora o uso de FluentValidation como alternativa para simplificar e trazer maior flexibilidade à escrita de regras de validação em aplicações ASP.NET Core. Para isto será empregado o package FluentValidation.AspNetCore.
A classe ComentarioValidator conterá as diversas regras esperadas para os dados a serem inseridos através da API REST:
- Este tipo herda de AbstractValidator<T> (namespace FluentValidation), referenciando ainda a classe Comentario;
- No construtor de ComentarioValidator chamadas ao método RuleFor permitirão via expressão lambda selecionar os campos que passarão por verificação, bem como as regras de validação para os mesmos;
- No exemplo aqui abordado foram especificadas regras através dos métodos NotEmpty (preenchimento obrigatório, desconsiderando strings contendo apenas espaços ou nulas), MinimumLength (tamanho mínimo em número de caracteres) e MaximumLength (tamanho máximo em número de caracteres);
- Outros exemplos de métodos usados na montagem de regras de validação são NotNull (valores não nulos), GreaterThan (maior que) e LessThan (menor que).
Ajustes também ocorrerão na classe Startup:
- O método AddFluentValidation será acionado em ConfigureServices (linha 25);
- O tipo ComentarioValidator foi adicionado por meio de uma chamada a AddTransient, a fim de que referências envolvendo o mesmo sejam preenchidas via mecanismo de injeção do ASP.NET Core (linha 27).
A classe permanecerá idêntica ao exemplo da seção anterior e sem qualquer menção ao uso de FluentValidation, uma vez que o uso do atributo ApiController também é compatível com esta biblioteca:
A seguir temos um exemplo envolvendo o preenchimento incorreto de dados (testes via Postman), bem como a apresentação de mensagens de alerta definidas por meio de FluentValidation:
Esse exemplo também está no GitHub:
ASP.NET Core 2.2 + ApiController + Dapper.Contrib + FluentValidation + SQL Server
Polly: aplicações resilientes e um melhor tratamento de falhas
Uma ocorrência bastante comum, sobretudo em aplicações legadas, é a presença de inúmeros blocos try-catch encadeados ou não e geralmente relacionados a um mesmo fluxo de processamento. Muito embora esta prática atenda a muitas necessidades relacionadas ao tratamento de erros, há uma forte tendência em se chegar a um código extenso e difícil manutenção conforme o projeto cresce.
E que tal implementarmos mecanismos de recuperação de falhas de maneira elegante, empregando para isto padrões como Retry, Fallback, Timeout e Circuit Breaker e obtendo assim aplicações mais resilientes? É o que a biblioteca Polly se propõe a fazer dentro da plataforma .NET, possuindo total compatibilidade com .NET Standard (o que viabiliza seu uso em .NET Core/ASP.NET Core, Xamarin, ASP.NET clássico, .NET Full).
Recentemente detalhei o uso de Polly implementando o pattern Retry no artigo (inclui repositório no GitHub):
.NET Core + Polly + JWT: tratando de forma resiliente a expiração de tokens
Se você chegou até aqui e tem interesse em conhecer mais sobre o desenvolvimento de soluções Web utilizando o Azure, aproveito este espaco para mais um convite… Que tal aprender mais sobre a nuvem Microsoft, em um workshop que acontecerá durante um sábado (dia 21/09) em São Paulo Capital e implementando na prática um case que combina o uso de tecnologias como Azure App Service, Azure SQL, Azure Storage, Azure Functions e Application Insights? Acesse então o link a seguir para efetuar sua inscrição com um desconto especial: http://bit.ly/anp-dicas-aspnet
E concluo este artigo deixando o link de uma live recente do Canal .NET, em que abordamos através de exemplos práticos o uso de alguns dos frameworks/tecnologias aqui mencionados, além de diversas outras soluções - MediatR, Polly, ASP.NET Core Identity, HTTP REPL, Entity Framework Core, Dapper Contrib, AspNetCore.Diagnostics.HealthChecks, xUnit, Fluent Assertions, FluentValidation e AutoMapper: