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:
GlobalConfiguration.BaseUrl
: A URL onde nossa API gateway está executando.ReRoutes
: Configuração de todas as rotas de uma requisição para outras APIs.ReRoutes.UpstreamPathTemplate
: O padrão de rota que corresponde com uma API.ReRoutes.UpstreamHttpMethod
: Define os verbos HTTP que serão roteados por essa configuração.ReRoutes.DownstreamPathTemplate
: A variável que criamos para passar para a próxima rota. Pode ser qualquer nome e mais do que uma, ex.: /foo/{var1}/data/{var2}
.ReRoutes.DownstreamScheme
: O protocolo que estamos utilizando. Neste caso http
.ReRoutes.DownstreamHostAndPorts
: O host e porta onde a API de destino está executando.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.