I recently come across a Ocelot nuget package. What interest me that, we can implement API Gateways in ASP.NET core using Ocelot. But before explaining What is Ocelot. Let me start first with Microservices, Then why we need Ocelot
What Is Microservices Architecture?
Microservices Architecture, some time called as service-oriented architecture (SOA) , is one of software architectural pattern where application or services are lightweight, loosely coupled, modular in nature.
These services can be built to execute on various platforms and independently developed, tested, deployed, and managed. In general, API Gateway is used to layer before these microservices . All services/api in microservices are consumed through API Gateway
Example : Service fabric, Containers
What is API Gateway?
API Gateway act like mediator between the client and back end micro services. Key features of the API Gateway
Features:
- Routing
- Request Aggregation
- Service Discovery with Consul & Eureka
- Service Fabric
- Kubernetes
- WebSockets
- Authentication
- Authorization
- Rate Limiting
- Caching
- Retry policies / QoS
- Load Balancing
- Logging / Tracing / Correlation
- Headers / Method / Query String / Claims Transformation
- Custom Middleware / Delegating Handlers
- Configuration / Administration REST API
- Platform / Cloud Agnostic
What is Ocelot ?
Ocelot is a .NET API Gateway. Ocelot supports all features of API Gateway, but We will see only few in this blog
We need back end service to test the ocelot gateway, back service would be anything , developed in any language. But in this example we have create a ASP. NET web app as back end service (https://localhost:5001/weatherforecast) and ran in background
Now All set , we are back end service ready , Let started implementing API Gateway in net core. Our goal is that API Gateway will route the incoming request to the Back end service endpoints (https://localhost:5001/weatherforecast)
API GATEWAY USING OCELOT :
Created asp net core empty application in visual studio (Create a new Project > Choose template ASP.NET Core EMPTY > Given Project name as Ocelot_Demo> Choose target framework as .net core 3.1 and authentication type as none.
ROUTING :
First thing after creation of application , Go to program.cs of the application. Add console log which could be very use in debugging
program.cs
namespace OCELOTDEMO
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).ConfigureLogging(logging=>logging.AddConsole());
}
}
Then add single nuget package (OCELOT) to the solution . To use Ocelot in application you just need to add two line in Startup.cs , One in ConfigureServices method and Another in Configure
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OCELOTDEMO
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public 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!");
});
});
app.UseOcelot().Wait();
}
}
}
Next we need to two ocelot json configuration file to solution , One as "ocelot.json" and another as "ocelot.Development.json"
Add ocelot configuration in ocelot.Development.json
"Routes": [
{
"DownStreamPathTemplate": "/weatherforecast",
"DownStreamScheme": "https",
"DownStreamHostAndPorts": [
{
"Host": "localhost",
"Port":5001
}
],
"UpStreamPathTemplate": "/api/weather",
"UpStreamHttpMethod": [ "Get" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:44355"
}
}
To know more about ocelot configuration, Please read their official documentation
Next is to change in program.cs to read ocelot config file
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OCELOTDEMO
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureAppConfiguration(config=>config.AddJsonFile($"ocelot.{env}.json"));
}).ConfigureLogging(logging=>logging.AddConsole());
}
}
Now run the OCELOTDEMO solution, And try to access the endpoint in browser with url https://localhost:44355/api/weather , Your request route to back end service end point https://localhost:5001/weatherforecast and will get the response from back end service as
[{"date":"2022-10-05T18:19:22.865497+05:30","temperatureC":8,"temperatureF":46,"summary":"Warm"},{"date":"2022-10-06T18:19:22.8655139+05:30","temperatureC":51,"temperatureF":123,"summary":"Mild"},{"date":"2022-10-07T18:19:22.8655145+05:30","temperatureC":-19,"temperatureF":-2,"summary":"Hot"},{"date":"2022-10-08T18:19:22.8655147+05:30","temperatureC":10,"temperatureF":49,"summary":"Mild"},{"date":"2022-10-09T18:19:22.865515+05:30","temperatureC":41,"temperatureF":105,"summary":"Cool"}]
Rate Limiting :
{"Routes": [{"DownStreamPathTemplate": "/weatherforecast","DownStreamScheme": "https","DownStreamHostAndPorts": [{"Host": "localhost","Port": 5001}],"UpStreamPathTemplate": "/api/weather","UpStreamHttpMethod": [ "Get" ],"RateLimitOptions": {"ClientWhitelist": [],"EnableRateLimiting": true,"Period": "1s","PeriodTimespan": 1,"Limit": 1}}],"GlobalConfiguration": {"BaseUrl": "https://localhost:44355"}}
Source code of Backend : git@github.com:shedev/Demo.BackEndServices.WebAPI.git
Source code of API gateway : git@github.com:shedev/OCELOTDEMO.git
Official documentation of Ocelot: https://ocelot.readthedocs.io/
No comments:
Post a Comment