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; } }
}
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; } }
}
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.
Feito isso, seguindo o padrão da Clean Architecture
na camada de Infrastructure vamos criar uma pasta Integration e a seguinte estrutura dentro dela.
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; } }
}
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); }
}
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); }
}
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; } }
}
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
.
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(); } }
}
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.
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
.
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
Retorno da Api com os dados completos do usuário, inclusive endereço
Registro salvo banco de dados.
Na próxima parte vamos implementar a parte de segurança da nossa api utilizando o JWt Token, ate lá.