Marx J. Moura

20 August 2019

API gateway with ASP.NET Core and Ocelot

API gateway with Ocelot

Thinking about the microservices architecture pattern leads us to think of the API gateway. So, let's disccuss a bit and implement an API gateway using the Ocelot framework.

I've read two great articles, the microservices.io and the Microsoft documentation that help me a lot to understand the use of the API gateway. I also implemented an API gateway on my open source project Storefront Community.

Briefly an API gateway is an entry point for all or our services. This allow us to have a single domain for all of our APIs, rather than having a subdomain for each of them. With the subdomains we have the concern about SSL for each API, frontend connecting to several APIs generating more effort to deal with authorization, among others.

The Ocelot is an open source API gateway framework for .NET. Once we have finished implementing our API gateway we will achieve this:

Instead of this (without API gateway):

For authorization we will use the ASP.NET Core Identity, but we will discuss this in a next post.

So, let's start. I'm using .NET Core CLI and I presume that you already have the .NET Core SDK installed.

First create a folder to the project using de command mkdir and go to it using the command cd:

mkdir ApiGateway

cd ApiGateway

Inside the ApiGateway folder let's create an empty web project:

dotnet new web

Then add the Ocelot package to the project:

dotnet add package Ocelot

The ApiGateway.csproj file should look like this:

<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>

Still in the root folder of the project let's create the ocelot.json configuration file with the following content:

{
  "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
        }
      ]
    }
  ]
}

I will explain what means each property but you may also refer to Ocelot documentation:

The result is: every request using the methods GET, POST, PUT, DELETE and OPTIONS from http://localhost:5000/mocky/{paht} will be routed to http://www.mocky.io/v2/{path} (do not confuse with redirect). Where the path can be any value and will be passed to the target API.

Now we need our API gateway to read the configuration file ocelot.json. We will do this through the Program class and for that, we will replace the content of the Program.cs file with the following:

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>();
    }
}

In order for our API gateway to use Ocelot we need to configure it in the Startup class. Replace the content of the Startup.cs file with the following:

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();
        }
    }
}

Now, let's run our API gateway (by default at http://localhost:5000):

dotnet run

When you access http://localhost:5000/mocky/5185415ba171ea3a00704eed from your browser you should get:

{"hello": "world"}

And what is mocky.io? Is an fake RESTful API where we can mock JSON responses.

marxjmoura

I'm Marx J. Moura. In this blog I write about microservice architecture and web application development.