Implementação de Clientes HTTP Declarativos com SummerBoot.Feign no .NET

O componente Feign, integrado ao ecossistema .NET através do framework SummerBoot, oferece uma abordagem declarativa para o consumo de serviços HTTP. Em vez de escrever manualmente o código para requisições HTTP, os desenvolvedores podem definir interfaces de serviço com anotações simples, permitindo que o Feign gere automaticamente as implementações de cliente. Isso simplifica o acesso a APIs remotas, fazendo com que chamadas a serviços externos se assemelhem a invocações de métodos locais.

A base do Feign é construída sobre clientes HTTP, abstraindo a complexidade das operações de rede e serialização/desserialização de dados. Além de sua funcionalidade principal, o Feign no SummerBoot disponibiliza recursos avançados:

  • Intercepção Personalizada: Permite a injeção de lógica customizada antes ou depois das requisições, ideal para logs, autenticação ou manipulação de cabeçalhos.
  • Encapsulamento de Chamadas: Reduz a verbosidade do código, concentrando a lógica de requisição HTTP dentro das interfaces de serviço.
  • Integração com Nacos: Facilita a descoberta e registro de serviços em ambientes de microsserviços.
  • Tratamento de Resiliência: Capacidade de integração com bibliotecas como Polly para implementar padrões de resiliência, como retries e circuit breakers.
  • Segurança: Suporte para integração com tokens JWT para autorização e autenticação.

As anotações para mapeamento de métodos HTTP são intuitivas:

Método HTTP Anotação Feign
GET [GetMapping]
PUT [PutMapping]
DELETE [DeleteMapping]
POST [PostMapping]

Exemplo de Uso Simplificado do Feign

Para demonstrar o uso do Feign, vamos configurar três projetos:

  1. ServicoApiUsuarios: Um projeto ASP.NET Core que expõe endpoints HTTP.
  2. InterfacesFeign: Uma biblioteca de classes que define as interfaces de cliente Feign.
  3. ClienteConsumidor: Um projeto ASP.NET Core que consome o ServicoApiUsuarios através das interfaces Feign.

1. Projeto ServicoApiUsuarios (Provedor de API)

Este projeto oferece uma API RESTful para gerenciamento de usuários. Expondo endpoints GET e POST.

Modelo de Dados:

public class DadosUsuario
{
    public int Id { get; set; }
    public string NomeExibicao { get; set; }
}

Controller (GerenciadorUsuariosController.cs):

[ApiController]
[Route("[controller]/[action]")]
public class GerenciadorUsuariosController : ControllerBase
{
    [HttpGet]
    public List<DadosUsuario> ObterListaUsuarios()
    {
        List<DadosUsuario> usuarios = new()
        {
            new(){Id = 1, NomeExibicao = "João Silva"},
            new(){Id = 2, NomeExibicao = "Maria Oliveira"}
        };
        return usuarios;
    }

    [HttpPost]
    public DadosUsuario CriarNovoUsuario([FromBody] DadosUsuario usuario)
    {
        // Lógica para salvar o usuário, aqui apenas o retornamos
        return usuario;
    }
}

2. Projeto InterfacesFeign (Definição do Cliente Feign)

Neste projeto, definimos as interfaces que o Feign usará para gerar os clientes. Primeiramente, configure os serviços no Program.cs ou Startup.cs:

builder.Services.AddSummerBoot();
builder.Services.AddSummerBootFeign();

A interface IServicoExternoUsuarios é onde declaramos os métodos para consumir a API. A anotação [FeignClient] especifica a URL base do serviço externo, e as anotações nos métodos mapeiam para os endpoints específicos.

using SummerBoot.Feign;
using SummerBoot.Feign.Attributes;
using System.Collections.Generic;
using System.Threading.Tasks;

// Suponha que DadosUsuario esteja definido em uma biblioteca compartilhada
// ou seja recriado neste projeto.
public class DadosUsuario
{
    public int Id { get; set; }
    public string NomeExibicao { get; set; }
}

[FeignClient(Url = "http://192.168.10.13:5152")] // URL do ServicoApiUsuarios
public interface IServicoExternoUsuarios
{
    [GetMapping("/GerenciadorUsuarios/ObterListaUsuarios")]
    Task<List<DadosUsuario>> RecuperarTodosUsuarios();

    [PostMapping("/GerenciadorUsuarios/CriarNovoUsuario")]
    Task<DadosUsuario> RegistrarUsuario([Body] DadosUsuario usuario);
}

É importante notar que os métodos da interface Feign devem retornar Task<>, indicando que são operações assíncronas. O Feign gera uma implementação de proxy para essa interface, lidando com a execução da requisição HTTP subjacente.

A anotação [FeignClient] permite diversas configurações, como:

  • Url: A URL base do serviço.
  • IsIgnoreHttpsCertificateValidate: Define se a validação de certificado HTTPS deve ser ignorada (útil em ambientes de desenvolvimento).
  • InterceptorType: Epsecifica um tipo de interceptador personalizado para a requisição.
  • Timeout: Define o tempo limite da requissição em segundos.

A anotação [Body] indica que o parâmetro do método deve ser enviado no corpo da requisição. Por padrão, o Feign serializa o objeto para JSON, mas também suporta submissão via formulário.

3. Projeto ClienteConsumidor (Consumidor da API)

Este projeto integra a interface Feign e a utiliza para chamar o serviço remoto. Primeiro, configure os serviços:

builder.Services.AddSummerBoot();
builder.Services.AddSummerBootFeign();

Em um Controller, injetamos a interface Feign e invocamos seus métodos como se fossem locais:

[ApiController]
[Route("[controller]/[action]")]
public class ConsumidorApiUsuariosController : ControllerBase
{
    private readonly IServicoExternoUsuarios _servicoUsuariosExterno;

    public ConsumidorApiUsuariosController(IServicoExternoUsuarios servicoUsuariosExterno)
    {
        _servicoUsuariosExterno = servicoUsuariosExterno;
    }

    [HttpGet]
    public async Task<List<DadosUsuario>> BuscarUsuariosRemotos()
    {
        return await _servicoUsuariosExterno.RecuperarTodosUsuarios();
    }

    [HttpPost]
    public async Task<DadosUsuario> EnviarDadosUsuario(DadosUsuario usuario)
    {
        return await _servicoUsuariosExterno.RegistrarUsuario(usuario);
    }
}

Configuração Dinâmica de URLs

Para maior flexibilidade, as URLs e paths podem ser lidos de arquiovs de configuração (como appsettings.json) usando a sintaxe ${}. Por exemplo:

appsettings.json:

{
  "ConfiguracaoServicos": {
    "UrlApiUsuarios": "http://localhost:5152",
    "CaminhoUsuarios": "/GerenciadorUsuarios/ObterListaUsuarios"
  }
}

Uso na interface Feign:

[FeignClient(Url = "${ConfiguracaoServicos:UrlApiUsuarios}")]
public interface IServicoExternoUsuarios
{
    [GetMapping("${ConfiguracaoServicos:CaminhoUsuarios}")]
    Task<List<DadosUsuario>> RecuperarTodosUsuarios();
    // ...
}

Tags: SummerBoot Feign .NET HTTP Client microservices

Publicado em 6-28 21:35