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 running, we made them in previous 2 tutorials. Now after installing Ocelot API Gateway, these microservices will communicate through 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 Empty project.

asp.net core Empty project

Name the project as OcelotGateway.

project name ocelot

On the next screen select .NET 8.0 for the version and click the Create button.

ASP.NET Core version 8.0

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 add Ocelot configurations as shown in highlighted manner:

using Ocelot.DependencyInjection;
using Ocelot.Middleware;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
builder.Services.AddOcelot();

var app = builder.Build();

await app.UseOcelot();

app.MapGet("/", () => "Hello World!");

app.Run();

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

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, and also 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.

In the below image I called the uri of the 2nd mircoservice with the drone id – https://localhost:44399/gateway/process?droneId=443bcd46-05fc-48be-b0dd-fc1333ab8507. The API gave the combined data from the two Microservice as before.

ocelot api request

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:

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