DEV Community

Hernani Almeida
Hernani Almeida

Posted on • Updated on

Api Rest .Net completa com JwtToken integração com api ViaCep utilizando padrão de arquitetura clean architecture - parte 2

Ferramentas necessárias:

Seguimos com a construção da nossa api, neste artigo vamos estruturar nossa api para salvar um usuário integrando com a api ViaCep para buscar os dados de endereço desse usuário através do Cep.
Vamos criar estrutura para salvar um usuário, vamos criar a entity User que ira conter os dados de endereço do usuário através da classe Endereco.

User

using FirstApi.Domain.ValueObjects;
using FirstApi.Infrastructure.Integration.ViaCep;

namespace FirstApi.Domain.Entities
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Email { get; set; }
        public string? Password { get; set; }
        public Endereco? Endereco { get; set; }

        public Endereco GetEndereco(ViaCepResponse response)
        {
            Endereco endereco = new Endereco();
            if(response is null)
            {
                return endereco;
            }
            endereco.Complemento = response.Complemento;
            endereco.Cep = response.Cep;
            endereco.Bairro = response.Bairro;
            endereco.Logradouro = response.Logradouro;
            endereco.Localidade = response.Localidade;
            endereco.Cep = response.Cep;
            endereco.Unidade = response.Unidade;
            endereco.Uf = response.Uf;
            return endereco;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Endereco

using FirstApi.Infrastructure.Integration.ViaCep;

namespace FirstApi.Domain.ValueObjects
{
    public class Endereco
    {
        public string? Cep { get; set; }
        public string? Logradouro { get; set; }
        public string? Complemento { get; set; }
        public string? Unidade { get; set; }
        public string? Bairro { get; set; }
        public string? Localidade { get; set; }
        public string? Uf { get; set; }

    }
}
Enter fullscreen mode Exit fullscreen mode

A estrutura vamos seguir a mesma que a parte 1 desse artigo, ou se preferir pode visitar o repositorio contendo o código para usar como referencia.
Na classe de entrada de dados para registrar nosso usuário vamos receber um parâmetro Cep, através desse parâmetro vamos realizar uma chamada para a api ViaCep para preencher os dados de endereço do usuário, vamos utilizar a lib Refit para realizar essa integração.
Conforme vimos no artigo anterior vamos instalar essas duas dependências no projeto.

Image description

Feito isso, seguindo o padrão da Clean Architecture na camada de Infrastructure vamos criar uma pasta Integration e a seguinte estrutura dentro dela.

Image description

ViaCepResponse classe que mapeara o response oriundo da api ViaCep

namespace FirstApi.Infrastructure.Integration.ViaCep
{
    public class ViaCepResponse
    { 
        public string? Cep { get; set; }
        public string? Logradouro { get; set; }
        public string? Complemento { get; set; }
        public string? Unidade { get; set; }
        public string? Bairro { get; set; }
        public string? Localidade { get; set; }
        public string? Uf {  get; set; }

}
}
Enter fullscreen mode Exit fullscreen mode

IViaCepIntegrationRefit classe onde configuramos o client de acesso ao endpoint da api ViaCep

using Refit;

namespace FirstApi.Infrastructure.Integration.ViaCep.Refit
{
    public interface IViaCepIntegrationRefit
    {
        [Get("/ws/{cep}/json/")]
        public Task<ApiResponse<ViaCepResponse>> FindEnderecoByCep(string cep);
    }
}
Enter fullscreen mode Exit fullscreen mode

IViaCepIntegrationService contrato do serviço que utilizara o client para realizar a chamada em nossa logica.

namespace FirstApi.Infrastructure.Integration.ViaCep
{
    public interface IViaCepIntegrationService
    {
        public Task<ViaCepResponse> FindEnderecoByCep(string cep);
    }
}
Enter fullscreen mode Exit fullscreen mode

ViaCepIntegrationService serviço que implementa o serviço para buscar os dados de Endereço do usuário.


using FirstApi.Infrastructure.CustomException;
using FirstApi.Infrastructure.Integration.ViaCep.Refit;

namespace FirstApi.Infrastructure.Integration.ViaCep
{
    public class ViaCepIntegrationService : IViaCepIntegrationService
    {
        private readonly IViaCepIntegrationRefit _refit;

        public ViaCepIntegrationService(IViaCepIntegrationRefit refit)
        {
            _refit = refit;
        }

        async Task<ViaCepResponse> IViaCepIntegrationService.FindEnderecoByCep(string cep)
        {
            var responseData = await _refit.FindEnderecoByCep(cep);
            if(responseData is null || !responseData.IsSuccessStatusCode)
            {
                throw new AppException("Error on integration with extern api");
            }

            return responseData.Content;
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Vamos agora adicionar o escopo de cada serviço na nossa classe Program.cs, para podermos realizar a injeção de dependência, e configurar o RefitClient também em nossa classe Program.cs.

Image description

Nossa classe Program.cs ficara assim.


using FirstApi.Application.UseCases.CasesEmployer.ConsultEmployer;
using FirstApi.Application.UseCases.CasesEmployer.DeleteEmployer;
using FirstApi.Application.UseCases.CasesEmployer.Register;
using FirstApi.Application.UseCases.CasesEmployer.UpdateEmployer;
using FirstApi.Application.UseCases.CasesUser.ConsultUser;
using FirstApi.Application.UseCases.CasesUser.DeleteUser;
using FirstApi.Application.UseCases.CasesUser.RegisterUser;
using FirstApi.Application.UseCases.CasesUser.UpdateUser;
using FirstApi.Application.UseCases.PasswordHasher;
using FirstApi.Domain.Repositories;
using FirstApi.Infrastructure.Data;
using FirstApi.Infrastructure.Handler;
using FirstApi.Infrastructure.Integration.ViaCep;
using FirstApi.Infrastructure.Integration.ViaCep.Refit;
using FirstApi.Infrastructure.Repositories;
using Microsoft.EntityFrameworkCore;
using Refit;

namespace FirstApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            // Configure logging
            builder.Logging.ClearProviders();
            builder.Logging.AddConsole();
            builder.Logging.AddDebug();
            // Configure data base access
            builder.Services.AddDbContext<SystemDbContext>(
                options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
            // Add repositories to the container.
            builder.Services.AddScoped<IEmployerRepository, EmployerRepository>();
            builder.Services.AddScoped<IUserRepository, UserRepository>();
            // Add services to the container.
            // employer
            builder.Services.AddScoped<IRegisterEmployerService, RegisterEmployerService>();
            builder.Services.AddScoped<IUpdateEmployerService, UpdateEmployerService>();
            builder.Services.AddScoped<IConsultEmployerService, ConsultEmployerService>();
            builder.Services.AddScoped<IDeleteEmployerService, DeleteEmployerService>();
            // user
            builder.Services.AddScoped<IRegisterUserService, RegisterUserService>();
            builder.Services.AddScoped<IUpdateUserService, UpdateUserService>();
            builder.Services.AddScoped<IConsultUserService, ConsultUserService>();
            builder.Services.AddScoped<IDeleteUserService, DeleteUserService>();
            builder.Services.AddScoped<IPasswordHasher, PasswordHasher>();
            // client viacep
            builder.Services.AddScoped<IViaCepIntegrationService, ViaCepIntegrationService>();
            // Add client refit
            builder.Services.AddRefitClient<IViaCepIntegrationRefit>().ConfigureHttpClient(c =>
            {
                c.BaseAddress = new Uri("https://viacep.com.br");
            }
            );

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseHttpsRedirection();

            app.UseAuthorization();

            // global error handler
            app.UseMiddleware<GlobalExceptionHandler>();

            app.MapControllers();

            app.Run();
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Dentro do nosso UserController chamamos a api ViaCep para popularmos nosso objeto ViaCepResponse, que e passada como parâmetro para nosso serviço junto com o input de entrada de dados.

Image description

Dentro do nosso serviço utilizamos o método Convert implementado dentro da nossa classe de entrada de dados, seguindo o conceito de não termos classes anêmicas em nosso projeto, que ira retornar um objeto User.

Image description

Image description

Lembre-se de seguir o passo a passo do artigo 1 pois será necessário mapear a entity User e criar a tabela Users no nosso database, feito isso tudo já esta pronto para testarmos nossa api.

Requisição POST
Image description
Retorno da Api com os dados completos do usuário, inclusive endereço

Image description

Registro salvo banco de dados.

Image description

Na próxima parte vamos implementar a parte de segurança da nossa api utilizando o JWt Token, ate lá.

Parte 3

linkedin
github

Top comments (2)

Collapse
 
diegobrandao profile image
Diego de Sousa Brandão

Muito bom

Collapse
 
2020nani profile image
Hernani Almeida

Vlw maninho pelo feedback