Marx J. Moura

20 de agosto de 2019

API gateway com ASP.NET Core e Ocelot

API gateway com Ocelot

Pensar no padrão de arquitetura de microsserviços nos leva a pensar em API gateway. Então, vamos discutir um pouco e implementar uma API gateway usando o framework Ocelot .

Eu li dois ótimos artigos, a microservices.io e a documentação da Microsoft, que me ajudaram muito a entender o uso de uma API gateway. Eu também implementei uma API gateway no meu projeto de código aberto Storefront Community.

De maneira breve, uma API gateway é um ponto de entrada para todos os nossos serviços. Isso nos permite ter um único domínio para todas as nossas APIs, ao invés de ter um subdomínio para cada uma delas. Com subdomínios nós temos a preocupação de SSL para cada API, frontend se conectando com múltiplas APIs gerando mais esforço para lidar com autorização, entre outros.

O Ocelot é framwork de código aberto para construir API gateway com .NET. Assim que finalizarmos a implementação da nossa API gateway alcançaremos isso:

Ao invés disso (sem API gateway):

Para autorização nós usaremos o ASP.NET Core Identity, mas discutiremos isso em um outro post.

Então, vamos começar. Eu estou usando o .NET Core CLI e admitindo que você já tem o .NET Core SDK instalado.

Primeiro crie um diretório para o projeto usando o comando mkdir e navege para ele usando o comando cd:

mkdir ApiGateway

cd ApiGateway

Dentro do diretório ApiGateway vamos criar um projeto web vazio:

dotnet new web

A seguida adicione o pacote do Ocelot ao projeto:

dotnet add package Ocelot

O arquivo ApiGateway.csproj deve estar parecido com isso:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Ocelot" Version="13.5.2" />
  </ItemGroup>
</Project>

Ainda no diretório raíz do projeto vamos criar o arquivo de configuração ocelot.json com o seguinte conteúdo:

{
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5000"
  },
  "ReRoutes": [
    {
      "UpstreamPathTemplate": "/mocky/{path}",
      "UpstreamHttpMethod": [
        "Get",
        "Post",
        "Put",
        "Delete",
        "Options"
      ],
      "DownstreamPathTemplate": "/v2/{path}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "www.mocky.io",
          "Port": 80
        }
      ]
    }
  ]
}

Eu explicarei o que significa cada propriedade mas você também pode usar a documentação do Ocelot como referência:

O resultado é: toda requisição usando os métodos GET, POST, PUT, DELETE e OPTIONS de http://localhost:5000/mocky/{paht} serão roteadas para http://www.mocky.io/v2/{path} (não confundir com redirecionamento). Onde path pode assumir qualquer valor e será repassado para API de destino.

Agora precisamos fazer com que nossa API gateway leia o arquivo de configuração ocelot.json. Iremos fazer isso através da classe Program e para isso, vamos substituir o conteúdo do arquivo Program.cs com o seguinte:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace ApiGateway
{
    public sealed class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((host, config) =>
                {
                    config.AddJsonFile("ocelot.json");
                })
                .UseStartup<Startup>();
    }
}

Para que nossa gateway API utilize o Ocelot precisamos configurá-la na classe Startup. Substitua o conteúdo do arquivo Startup.cs pelo seguinte:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

namespace ApiGateway
{
    public sealed class Startup
    {
        public readonly IConfiguration _configuration;

        public Startup(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot(_configuration);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseOcelot().Wait();
        }
    }
}

Agora, vamos executar nossa API gateway (por padrão em http://localhost:5000):

dotnet run

Quando você acessar http://localhost:5000/mocky/5185415ba171ea3a00704eed no seu browser você deve obter:

{"hello": "world"}

E o que é o mocky.io? É uma RESTful API fictícia onde podemos simular respostas JSON.

marxjmoura

Eu sou Marx J. Moura. Neste blog escrevo sobre arquitetura de microsserviços e desenvolvimento de aplicações web.