Microservices API Gateway to unify Multiple Microservices

Microservices API Gateway to unify Multiple Microservices

In a Microservices architecture there are lots of URL where request to the microservices is made. Therefore, API Gateway like Ocelot comes to be very handy. An API Gateway transforms the Incoming HTTP Request from the client and forward it to an appropriate Microservice. Ocelot has a JSON configuration file that states the upstream and downstream routes.

Upstream Request is the Request that is made by the Client to the API Gateway while Downstream request is the request made by the API Gateway to the Microservice.

You can find the complete Source Code at my GitHub Repository.

We have our 2 microservices, now after installing Ocelot API gateway, the microservices will communicate through API Gateway. Similarly, the client (i.e. browser) will communicate with the microservices through the API Gateway. I have shown this in the below image.

ocelot api gateway

Building Ocelot API Gateway

Let us build Ocelot API Gateway for our Drone Pizza Delivery application. So open Visual Studio and create a new ASP.NET Core Web Application.

asp.net core web application

Name the project as OcelotGateway.

project name ocelot

Select ASP.NET Core Empty template and click the Create button.

ASP.NET Core Empty Template

An empty ASP.NET Core App will be created.

Next, Install Ocelot package from NuGet.

ocelot nuget

Let’s now configure Ocelot. So open Program.cs file and change the CreateHostBuilder method as follows.

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config
            .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
            .AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
        });

I have added a json file called ocelot.json which the app can access. In this file the ocelot configuration routes will be kept.

Next, navigate to the Startup.cs file and add Ocelot to the ConfigureServices method.

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

Also add Ocelot middleware to the Configure method:

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

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });

    await app.UseOcelot();
}

Configuring Routes for Ocelot API Gateway

Now coming to the most important part which is the formation of routes for Ocelot API Gateway. So create ocelot.json file on the root of the app and add to it the following code:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/order",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44393
        }
      ],
      "UpstreamPathTemplate": "/gateway/order",
      "UpstreamHttpMethod": [ "GET", "POST" ]
    }
  ]
}

Inside the Routes node we add the routes for Ocelot API Gateway.

DownstreamPathTemplate denotes the route of the Microservice endpoint.

DownstreamScheme is the scheme of the Microservice, here it is HTTPS.

DownstreamHostAndPorts defines the host and port of the Microservice.

UpstreamPathTemplate is the path at which the client will request the Ocelot API Gateway.

UpstreamHttpMethod are the supported HTTP Methods to the API Gateway. Note that Ocelot will sends a similar HTTP method request to the microservice as well.

The above route we made is for the CommandCenter microservice. Recall that the URI of this microservice was https://localhost:44393/order. I have set the UpstreamHttpMethod to be GET and POST, so this route will target the GetAsync and PostAsync methods of the OrderController.

The value for UpstreamPathTemplate is set as /gateway/order this means we can call the GetAsync and PostAsync methods of the microservices from the Ocelot API Gateway URL which is https://localhost:44399/gateway/order.

Let us now test it with Postman. Make sure the OcelotGateway app is running, next run the CommandCenter microservice.

Now in Postman make a get request to https://localhost:44399/gateway/order and it will give you all the orders. See the below image where I have shown this:

ocelot api gateway integration

Now let us add other routes for GetByIdAsync, PutAsync and DeleteAsync methods which also needs order id value in the URL.

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/order",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44393
        }
      ],
      "UpstreamPathTemplate": "/gateway/order",
      "UpstreamHttpMethod": [ "GET", "POST" ]
    },
    {
      "DownstreamPathTemplate": "/order/{id}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44393
        }
      ],
      "UpstreamPathTemplate": "/gateway/order/{id}",
      "UpstreamHttpMethod": [ "GET", "PUT", "DELETE" ]
    }
  ]
}

In the second route notice I have specified:

DownstreamPathTemplate value as /order/{id} which is the URI of the CommandService microservice.

UpstreamPathTemplate value as “/gateway/order/{id}”.

UpstreamHttpMethod value to be GET, PUT and DELETE.

So GetByIdAsync, PutAsync and DeleteAsync methods which now be accessed from https://localhost:44399/gateway/order/{id}.

In the same way we can add the routes for the ProcessCenter miroservice also. Below I have added the route for the GetAsync and PostAsync methods of the ProcessController.

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/order",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44393
        }
      ],
      "UpstreamPathTemplate": "/gateway/order",
      "UpstreamHttpMethod": [ "GET", "POST" ]
    },
    {
      "DownstreamPathTemplate": "/order/{id}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44393
        }
      ],
      "UpstreamPathTemplate": "/gateway/order/{id}",
      "UpstreamHttpMethod": [ "GET", "PUT", "DELETE" ]
    },
    {
      "DownstreamPathTemplate": "/process",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44330
        }
      ],
      "UpstreamPathTemplate": "/gateway/process",
      "UpstreamHttpMethod": [ "GET", "POST" ]
    }
  ]
}

So now ProcessCenter microservice can be accessed on the URL – https://localhost:44399/gateway/process.

Include Ocelot API Gateway URL in ProcessCenter microservice API code

The ProcessCenter microservice also calls the CommandCenter Microservice. We can now change the URL with that of the Ocelot API Gateway.

So in the ConfigureServices method change the URL:

services.AddHttpClient<OrderClient>(a =>
{
    a.BaseAddress = new Uri("https://localhost:44399");
})
.AddTransientHttpErrorPolicy(b => b.Or<TimeoutRejectedException>().WaitAndRetryAsync(
    5,
    c => TimeSpan.FromSeconds(Math.Pow(2, c))
))
.AddTransientHttpErrorPolicy(b => b.Or<TimeoutRejectedException>().CircuitBreakerAsync(
    3,
    TimeSpan.FromSeconds(15)
))
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(1));

I have changed the port to 44399 which is that of the OcelotGateway app.

Next change the URL in the OrderClient.cs class as:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using static ProcessCenter.Infrastructure.Dtos;

namespace ProcessCenter.Clients
{
    public class OrderClient
    {
        private readonly HttpClient httpClient;
        public OrderClient(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        public async Task<IReadOnlyCollection<OrderDto>> GetOrderAsync()
        {
            var items = await httpClient.GetFromJsonAsync<IReadOnlyCollection<OrderDto>>("/gateway/order");
            return items;
        }
    }
}

This completes the integration of Ocelot API Gateway.

Conclusion

In this tutorial we covered Ocelot API Gateway and it’s integration in our Pizza Drone delivery microservices application. I hope you enjoyed learning it.

SHARE THIS ARTICLE

  • linkedin
  • reddit

ABOUT THE AUTHOR

I am Yogi S. I write DOT NET artciles on my sites hosting.work and yogihosting.com. You can connect with me on Twitter. I hope my articles are helping you in some way or the other, if you like my articles consider buying me a coffee - Buy Me A Coffee

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts based on your interest