Packages | Version & Downloads |
---|---|
AspNetCore.ApiGateway | |
AspNetCore.ApiGateway.Client | |
ts-aspnetcore-apigateway-client |
+ This project has been on-boarded by the .NET Foundation, in the Seed category.
Read more. Social Media: LinkedIn post.
More of my open-source projects | ||
---|---|---|
Live Health Checks | Real-Time Api Health Check Monitoring system | Browse |
The microservices architecture uses an Api Gateway as shown below.
The package:
- Makes creating an Api Gateway a breeze!!
- Swagger
- Authorization
- Filters
- Action
- Exception
- Result
- Load balancing
- Response caching
- Web sockets
- Event sourcing
- Request aggregation
- Middleware service
- Logging
- Clients available in
- .NET
- Typescript
Your Gateway API is a microservice which exposes endpoints that are a facade over your backend API endpoints.
- GET
- HEAD
- POST
- PUT
- PATCH
- DELETE
In the solution, there are 2 back end APIs : Weather API and Stock API.
For eg. To make a GET call to the backend API, you would set up an Api and a GET Route in your Gateway API's Api Orchestrator.
Then, the client app would make a GET call to the Gateway API which would make a GET call to the backend API using HttpClient.
Let us say you have a GET endpoint like this.
- HTTP GET - /weatherforecast/forecast
You add a Route for the backend GET call in the Api Orchrestrator.
You create a backend API with ApiKey called weatherservice for eg. And, a Route with RouteKey called forecast for eg.
So, the call to the Gateway would become:
- HTTP GET - /weatherservice/forecast
Add a reference to the package and...
-
Create an Api Orchestration.
You create an Api (weatherservice) and add a Route (forecast).
public static class ApiOrchestration
{
public static void Create(IApiOrchestrator orchestrator, IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var weatherService = serviceProvider.GetService<IWeatherService>();
var weatherApiClientConfig = weatherService.GetClientConfig();
orchestrator.StartGatewayHub = true;
orchestrator.GatewayHubUrl = "https://localhost:44360/GatewayHub";
orchestrator.AddApi("weatherservice", "http://localhost:63969/")
//Get
.AddRoute("forecast", GatewayVerb.GET, new RouteInfo { Path = "weatherforecast/forecast", ResponseType = typeof(IEnumerable<WeatherForecast>) })
//Head
.AddRoute("forecasthead", GatewayVerb.HEAD, new RouteInfo { Path = "weatherforecast/forecast" })
//Get with params
.AddRoute("typewithparams", GatewayVerb.GET, new RouteInfo { Path = "weatherforecast/types/{index}"})
//Get using custom HttpClient
.AddRoute("types", GatewayVerb.GET, new RouteInfo { Path = "weatherforecast/types", ResponseType = typeof(string[]), HttpClientConfig = weatherApiClientConfig })
//Get with param using custom HttpClient
.AddRoute("type", GatewayVerb.GET, new RouteInfo { Path = "weatherforecast/types/", ResponseType = typeof(WeatherTypeResponse), HttpClientConfig = weatherApiClientConfig })
//Get using custom implementation
.AddRoute("forecast-custom", GatewayVerb.GET, weatherService.GetForecast)
//Post
.AddRoute("add", GatewayVerb.POST, new RouteInfo { Path = "weatherforecast/types/add", RequestType = typeof(AddWeatherTypeRequest), ResponseType = typeof(string[])})
//Put
.AddRoute("update", GatewayVerb.PUT, new RouteInfo { Path = "weatherforecast/types/update", RequestType = typeof(UpdateWeatherTypeRequest), ResponseType = typeof(string[]) })
//Patch
.AddRoute("patch", GatewayVerb.PATCH, new RouteInfo { Path = "weatherforecast/forecast/patch", ResponseType = typeof(WeatherForecast) })
//Delete
.AddRoute("remove", GatewayVerb.DELETE, new RouteInfo { Path = "weatherforecast/types/remove/", ResponseType = typeof(string[]) })
.AddApi("stockservice", "http://localhost:63967/")
.AddRoute("stocks", GatewayVerb.GET, new RouteInfo { Path = "stock", ResponseType = typeof(IEnumerable<StockQuote>) })
.AddRoute("stock", GatewayVerb.GET, new RouteInfo { Path = "stock/", ResponseType = typeof(StockQuote) })
.AddHub("chatservice", ConnectionHelpers.BuildHubConnection, "2f85e3c6-66d2-48a3-8ff7-31a65073558b")
.AddRoute("room", new HubRouteInfo { InvokeMethod = "SendMessage", ReceiveMethod = "ReceiveMessage", ReceiveParameterTypes = new Type[] { typeof(string), typeof(string) } })
.AddEventSource("eventsourceservice", ConnectionHelpers.BuildEventSourceConnection, "281802b8-6f19-4b9d-820c-9ed29ee127f3")
.AddRoute("mystream", new EventSourceRouteInfo { ReceiveMethod = "ReceiveMyStreamEvent", Type = EventSourcingType.EventStore, OperationType = EventSourcingOperationType.PublishSubscribe, StreamName = "my-stream", GroupName = "my-group" });
}
}
- Hook up in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IWeatherService, WeatherService>();
//Api gateway
services.AddApiGateway();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My Api Gateway", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Api Gateway");
});
//Api gateway
app.UseApiGateway(orchestrator => ApiOrchestration.Create(orchestrator, app));
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//GatewayHub endpoint
endpoints.MapHub<GatewayHub>("/gatewayhub");
endpoints.MapControllers();
});
}
The Gateway Swagger appears as shown below:
To call the forecast Route on the weather service Api,
you can enter the Api key and Route key into Swagger as below:
This will hit the weatherforecast/forecast endpoint on the backend Weather API.
If you want, you can keep the ApiKey, RouteKey, backend API base urls and Route path,
in the appsettings.json, read it using a Config Service,
and pass it to the Api Orchestrator in the Create method.
Read more.
You can check out how the Api Gateway supported Verbs are used & Routing below.
Just like a Web API's Authorization Filter, the framework provides a Gateway Authorization Filter.
Here you can perform any kind of Authorization you like. There is no prescribed Authorization.
- Create a new or customize the default HttpClient used by all the routes, to hit the backend Api.
- Create a new or customize the default HttpClient which each route uses to hit the backend Api.
- Use your own custom implementation to hit the backend Api.
For Request aggregation, see this section.
Your Gateway's Api Orchestration is published by GET /api/Gateway/orchestration endpoint.
The Api Gateway uses ILogger<ApiGatewayLog> to create logs.
In your Gateway API project, this can be used to tap into these logs.
The Api Gateway supports a fixed set of endpoints.
All routes go through these endpoints.
The Client application has to talk to these endpoints of the Api Gateway.
A Client library is provided for: