Building API Gateway Using Ocelot In ASP.NET Core

Ocelot is aimed at people using .NET running a micro services / service orientated architecture who need a unified point of entry into their system.

Introduction

In this article, you will learn an easy way to build your API Gateway using Ocelot in ASP.NET Core. Maybe you will ask the question, what is API Gateway.

Let's take a look at the below screenshot first.

ASP.NET Core

The above screenshot can help you understand it clearly.

API Gateway is an entry to our systems. It contains lots of things, such as Routing, Authentication, Service discovery, Logging .etc.

Ocelot

Ocelot is aimed at people using .NET running a micro-services / service orientated architecture who need a unified point of entry into their system. You can visit this project’s Github page to find more information.

I will use a simple demo to show you how to use Ocelot.

Let's begin!

Step 1

Create three projects at first.

Project Name Project Type Description
APIGateway ASP.NET Core Empty entry of this demo
CustomersAPIServices ASP.NET Core Web API API Service that handles something about customers
ProductsAPIServices ASP.NET Core Web API API Service that handles something about products

ASP.NET Core

Step 2

Finish the two API services at first. Create a CustomersController in CustimersAPIServices project.

  1. [Route("api/[controller]")]  
  2. public class CustomersController : Controller  
  3. {          
  4.     [HttpGet]  
  5.     public IEnumerable<string> Get()  
  6.     {  
  7.         return new string[] { "Catcher Wong""James Li" };  
  8.     }  
  9.   
  10.     [HttpGet("{id}")]  
  11.     public string Get(int id)  
  12.     {  
  13.         return $"Catcher Wong - {id}";  
  14.     }              
  15. }  

In order to specify the App URL of this service, we should add UseUrls in the Program class.

  1. public static IWebHost BuildWebHost(string[] args) =>  
  2.         WebHost.CreateDefaultBuilder(args)  
  3.             .UseStartup<Startup>()  
  4.             .UseUrls("http://localhost:9001")  
  5.             .Build();  

Create a ProductsController in ProductsAPIServices project.

  1. [Route("api/[controller]")]  
  2. public class ProductsController : Controller  
  3. {  
  4.     [HttpGet]  
  5.     public IEnumerable<string> Get()  
  6.     {  
  7.         return new string[] { "Surface Book 2""Mac Book Pro" };  
  8.     }  
  9. }  

Edit the Program class to add UseUrls as well.

  1. public static IWebHost BuildWebHost(string[] args) =>  
  2.         WebHost.CreateDefaultBuilder(args)  
  3.             .UseStartup<Startup>()  
  4.             .UseUrls("http://localhost:9002")  
  5.             .Build();  

Note

You also can specify the App URL in the Project Options page.

ASP.NET Core

Step 3

Run the customer service and product service.

Open two terminals and use the "dotnet run" command to start them.

ASP.NET Core

As you can see, customer service is listening to http://localhost:9001 and product service is listening on http://localhost:9002.

Open the browser to verify whether the service is OK.

ASP.NET Core

Luckily, everything was going well.

Step 4

Now, we should turn to APIGateway project. We should install Ocelot package at first.

Install-Package Ocelot

After installing this package, you can find some dependence on it.

ASP.NET Core

Step 5

Add a configuration.json file.

  1. {  
  2.     "ReRoutes": [  
  3.         {  
  4.             "DownstreamPathTemplate""/api/customers",  
  5.             "DownstreamScheme""http",  
  6.             "DownstreamHost""localhost",  
  7.             "DownstreamPort": 9001,  
  8.             "UpstreamPathTemplate""/customers",  
  9.             "UpstreamHttpMethod": [ "Get" ]  
  10.         },  
  11.         {  
  12.             "DownstreamPathTemplate""/api/customers/{id}",  
  13.             "DownstreamScheme""http",  
  14.             "DownstreamHost""localhost",  
  15.             "DownstreamPort": 9001,  
  16.             "UpstreamPathTemplate""/customers/{id}",  
  17.             "UpstreamHttpMethod": [ "Get" ]  
  18.         },  
  19.         {  
  20.             "DownstreamPathTemplate""/api/products",  
  21.             "DownstreamScheme""http",  
  22.             "DownstreamPort": 9002,  
  23.             "DownstreamHost""localhost",  
  24.             "UpstreamPathTemplate""/api/products",  
  25.             "UpstreamHttpMethod": [ "Get" ]  
  26.         }  
  27.     ],  
  28.     "GlobalConfiguration": {  
  29.         "RequestIdKey""OcRequestId",  
  30.         "AdministrationPath""/administration"  
  31.     }  
  32. }  

This file is the configuration of the API Gateway. There are two sections to the configuration- an array of ReRoutes and a GlobalConfiguration. 

The ReRoutes are the objects that tell Ocelot how to treat an upstream request. The Global configuration is a bit hacky and allows overrides of ReRoute specific settings.

Take this part to explain the ReRoutes section.

  1. {  
  2.     "DownstreamPathTemplate""/api/customers/{id}",  
  3.     "DownstreamScheme""http",  
  4.     "DownstreamHost""localhost",  
  5.     "DownstreamPort": 9001,  
  6.     "UpstreamPathTemplate""/customers/{id}",  
  7.     "UpstreamHttpMethod": [ "Get" ]  
  8. }  

The items start with Downstream which means that our request will be forwarded to http://localhost:9001/api/customers/{id}.

The items start with Upstream which means that we should use HTTP GET method with /customers/{id}` to visit this service.

Step 6

Edit the Startup class so that we can use Ocelot in this project.

  1. public class Startup  
  2. {  
  3.     public Startup(IHostingEnvironment env)  
  4.     {  
  5.         var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder();  
  6.         builder.SetBasePath(env.ContentRootPath)      
  7.                //add configuration.json  
  8.                .AddJsonFile("configuration.json", optional: false, reloadOnChange: true)  
  9.                .AddEnvironmentVariables();  
  10.   
  11.         Configuration = builder.Build();  
  12.     }  
  13.   
  14.     //change  
  15.     public IConfigurationRoot Configuration { get; }  
  16.   
  17.     public void ConfigureServices(IServiceCollection services)  
  18.     {  
  19.         Action<ConfigurationBuilderCachePart> settings = (x) =>  
  20.         {  
  21.             x.WithMicrosoftLogging(log =>  
  22.             {  
  23.                 log.AddConsole(LogLevel.Debug);  
  24.   
  25.             }).WithDictionaryHandle();  
  26.         };  
  27.         services.AddOcelot(Configuration, settings);  
  28.     }  
  29.       
  30.     //don't use Task here  
  31.     public async void Configure(IApplicationBuilder app, IHostingEnvironment env)  
  32.     {  
  33.         await app.UseOcelot();  
  34.     }  
  35. }  

Don't forget to add the configuration.json file to the Configuration .

Step 7

This is a very important step to configure Ocelot.

We should create a new instance of IWebHostBuilder. And, don't use var here !!!

  1. public class Program  
  2. {  
  3.     public static void Main(string[] args)  
  4.     {  
  5.         IWebHostBuilder builder = new WebHostBuilder();  
  6.         builder.ConfigureServices(s =>  
  7.         {  
  8.             s.AddSingleton(builder);  
  9.         });  
  10.         builder.UseKestrel()  
  11.                .UseContentRoot(Directory.GetCurrentDirectory())  
  12.                .UseStartup<Startup>()  
  13.                .UseUrls("http://localhost:9000");  
  14.   
  15.         var host = builder.Build();  
  16.         host.Run();  
  17.     }  
  18. }  

We also specify the App URL of the API Gateway here.

Step 8

Run your API Gateway.

ASP.NET Core

As you can see, our API Gateway is running on http://localhost:9000

We open the browser to visit our services.

When visiting http://localhost:9000/api/products, we will get the result from http://localhost:9002/api/products .

When visiting http://localhost:9000/customers, we will get the result from http://localhost:9001/api/customers .

When visiting http://localhost:9000/customers/1, we will get the result from http://localhost:9001/api/customers/1.

Here is the source code you can find on my Github page.

Summary

This article introduced how to build API Gateway via Ocelot. Hope this will help you!

By the way, this is a very easy demo; there are some important things I did not mention in this article, such as Service discovery, Authentication, and Quality of Service