169
CHAPTER 5 | Designing and Developing Multi-Container and Microservice-Based .NET Applications
You install Ocelot and its dependencies in your ASP.NET Core project with
Ocel
ot’s
NuGet package
,
from Visual Studio.
Install-Package
Ocelot
In eShopOnContainers, its API Gateway implementation is a simple ASP.NET Core WebHost project,
and Ocelot’s middleware handles all the API Gateway features, a
s shown in the following image:
Figure 6-32. The OcelotApiGw base project in eShopOnContainers
This ASP.NET Core WebHost project is built with two simple files:
Program.cs
and
Startup.cs
.
The Program.cs just needs to create and configure the typical ASP.NET Core BuildWebHost.
namespace
OcelotApiGw
{
public
class
Program
{
public
static
void
Main
(
string
[] args)
{
BuildWebHost
(args).
Run
();
}
public
static
IWebHost
BuildWebHost
(
string
[] args)
{
var
builder = WebHost.
CreateDefaultBuilder
(args);
builder.
ConfigureServices
(s => s.
AddSingleton
(builder))
.
ConfigureAppConfiguration
(
ic => ic.
AddJsonFile
(Path.
Combine
(
"configuration"
,
"configuration.json"
)))
.
UseStartup
();
var
host = builder.
Build
();
return
host;
}
}
}
170
CHAPTER 5 | Designing and Developing Multi-Container and Microservice-Based .NET Applications
The important point here for Ocelot is the
configuration.json
file that you must provide to the
builder through the
AddJsonFile()
method. That
configuration.json
is where you specify all the
API
Gateway ReRoutes, meaning the external endpoints with specific ports and the correlated internal
endpoints, usually using different ports.
{
"ReRoutes"
:
[]
,
"GlobalConfiguration"
:
{}
}
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
allows overrides of ReRoute specific settings. It’s useful if you don’t want to manage lots of ReRoute
specific settings.
H
ere’s
a simplified example of
ReRoute configuration file
from one of the API Gateways from
eShopOnContainers.
{
"ReRoutes"
:
[
{
"DownstreamPathTemplate"
:
"/api/{version}/{everything}"
,
"DownstreamScheme"
:
"http"
,
"DownstreamHostAndPorts"
:
[
{
"Host"
:
"catalog-api"
,
"Port"
:
80
}
]
,
"UpstreamPathTemplate"
:
"/api/{version}/c/{everything}"
,
"UpstreamHttpMethod"
:
[
"POST"
,
"PUT"
,
"GET"
]
}
,
{
"DownstreamPathTemplate"
:
"/api/{version}/{everything}"
,
"DownstreamScheme"
:
"http"
,
"DownstreamHostAndPorts"
:
[
{
"Host"
:
"basket-api"
,
"Port"
:
80
}
]
,
"UpstreamPathTemplate"
:
"/api/{version}/b/{everything}"
,
"UpstreamHttpMethod"
:
[
"POST"
,
"PUT"
,
"GET"
]
,
"AuthenticationOptions"
:
{
"AuthenticationProviderKey"
:
"IdentityApiKey"
,
"AllowedScopes"
:
[]
}
}
]
,
"GlobalConfiguration"
:
{
"RequestIdKey"
:
"OcRequestId"
,
"AdministrationPath"
:
"/administration"
}
}
171
CHAPTER 5 | Designing and Developing Multi-Container and Microservice-Based .NET Applications
The main functionality of an Ocelot API Gateway is to take incoming HTTP requests and forward them
on to a downstream service, currently as another HTTP request. Ocelot’s describes the routing of one
request to another as a ReRoute.
For instance, let’s focus o
n one of the ReRoutes in the configuration.json from above, the
configuration for the Basket microservice.
{
"DownstreamPathTemplate"
:
"/api/{version}/{everything}"
,
"DownstreamScheme"
:
"http"
,
"DownstreamHostAndPorts"
:
[
{
"Host"
:
"basket-api"
,
"Port"
:
80
}
]
,
"UpstreamPathTemplate"
:
"/api/{version}/b/{everything}"
,
"UpstreamHttpMethod"
:
[
"POST"
,
"PUT"
,
"GET"
]
,
"AuthenticationOptions"
:
{
"AuthenticationProviderKey"
:
"IdentityApiKey"
,
"AllowedScopes"
:
[]
}
}
The DownstreamPathTemplate, Scheme, and DownstreamHostAndPorts
make the internal
microservice URL that this request will be forwarded to.
The port is the internal port used by the service. When using containers, the port specified at its
dockerfile.
The
Host
is a service name that depends on the service name resolution you are using. When using
docker-compose, the services names are provided by the Docker Host, which is using the service
names provided in the docker-compose files. If using an orchestrator like Kubernetes
or Service
Fabric, that name should be resolved by the DNS or name resolution provided by each orchestrator.
DownstreamHostAndPorts is an array that contains the host and port of any downstream services that
you wish to forward requests to. Usually this configuration will just contain one entry but sometimes
you might want to load balance requests to your downstream services and Ocelot lets you add more
than one entry and then select a load balancer. But if using Azure and any orchestrator it is probably a
better idea to load balance with the cloud and orchestrator infrastructure.
The UpstreamPathTemplate is the URL that Ocelot
will use to identify which
DownstreamPathTemplate to use for a given request from the client. Finally, the
UpstreamHttpMethod is used so Ocelot can distinguish between different requests (GET, POST, PUT)
to the same URL.
At this point, you could have a single Ocelot API Gateway (ASP.NET Core WebHost) using one or
multiple merged configuration.json files
or you can also store the
configuration in a
Consul KV store
.
But as introduced in the architecture and design sections, if you really want to have autonomous
microservices, it might be better to split that single monolithic API Gateway into multiple API
Gateways and/or BFF (Backend for Frontend). For that purpose, let’s see how to implement that
approach with Docker containers.
172
CHAPTER 5 | Designing and Developing Multi-Container and Microservice-Based .NET Applications
Dostları ilə paylaş: