Ocelot
允许您指定聚合多个普通Routes
的Aggregate Routes
(聚合路由),并将其响应映射到一个对象中。一般用于当您有一个客户端向服务器发出多个请求,而这些请求可以合并成一个的时候。此功能允许您通过Ocelot
实现前端类型结构的后端。
此功能是问题 79的一部分,并且作为问题 298的一部分进行了进一步改进。
为了设置它,你必须在ocelot.json
中做如下的事情。 这里我们已经指定了两个普通的Routes
,每一个都有一个Key
属性。 然后,我们使用RouteKeys
列表中的键指定组成两个Routes
的聚合,然后设置UpstreamPathTemplate
,它的工作方式与普通的Route
相似。 很明显,您不能在Routes
和Aggregates
之间复制UpstreamPathTemplates
。 除RequestIdKey
之外,您可以使用普通Route
所有的选项(在下面的陷阱中进行了解释)。
高级应用-注册你自己的聚合器
Ocelot只是基本的请求聚合,然后我们添加了一个更高级的方法,让用户从下游服务中获取响应,然后将它们聚合到响应对象中。
ocelot.json
的设置与基本聚合方法几乎相同,只需额外添加一个Aggregator
属性,如下所示。
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/laura",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 51881
}
],
"Key": "Laura"
},
{
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/tom",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 51882
}
],
"Key": "Tom"
}
],
"Aggregates": [
{
"ReRouteKeys": [
"Tom",
"Laura"
],
"UpstreamPathTemplate": "/",
"Aggregator": "FakeDefinedAggregator"
}
]
}
这里我们添加了一个叫FakeDefinedAggregator
的聚合器。当Ocelot
尝试聚合这个Route
的时候,会去查看这个聚合器。
为了使这个聚合器可用,我们必须像下面这样把FakeDefinedAggregator
添加到OcelotBuilder
。
services
.AddOcelot()
.AddSingletonDefinedAggregator<FakeDefinedAggregator>();
现在,当Ocelot尝试聚合上述Route
时,它会在容器中找到FakeDefinedAggregator
并使用它来聚合Route。 由于FakeDefinedAggregator
是在容器中注册,因此您可以将它需要的任何依赖项都添加到容器中,如下所示。
services.AddSingleton<FooDependency>();
services
.AddOcelot()
.AddSingletonDefinedAggregator<FooAggregator>();
在这个例子中FooAggregator
依赖FooDependency
,将会被容器解析。
除此之外,Ocelot
还允许您添加如下所示的瞬态聚合器。(参考.net core依赖注入,译者注)
services
.AddOcelot()
.AddTransientDefinedAggregator<FakeDefinedAggregator>();
为了实现一个聚合器,你必须实现这个接口。
public interface IDefinedAggregator
{
Task<DownstreamResponse> Aggregate(List<DownstreamResponse> responses);
}
使用此功能,您几乎可以做任何您想做的事情,因为DownstreamResponse
包含内容,头和状态代码。 如果需要,我们可以添加额外的东西,只需在GitHub
上提出这个问题。请注意,如果在向聚合中的Route
发出请求时HttpClient
抛出异常,那么您将不会获得其DownstreamResponse
,但您会获得其他请求成功的DownstreamResponse
。 如果某个请求抛出异常,则会被记录。
来自下游服务的基本期望JSON
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/laura",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 51881
}
],
"Key": "Laura"
},
{
"DownstreamPathTemplate": "/",
"UpstreamPathTemplate": "/tom",
"UpstreamHttpMethod": [
"Get"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 51882
}
],
"Key": "Tom"
}
],
"Aggregates": [
{
"ReRouteKeys": [
"Tom",
"Laura"
],
"UpstreamPathTemplate": "/"
}
]
}
你也可以设置Aggregate
的UpstreamHost
和ReRouteIsCaseSensitive
,和其他Routes
的作用是一样的。
如何路由/tom
返回 {“Age”: 19}
,路由/laura
返回{“Age”: 25}
,那么聚合之后的相应就如下所示。
{"Tom":{"Age": 19},"Laura":{"Age": 25}}
目前的聚合功能非常简单。 Ocelot
只是从你的下游服务获得响应,并将其复制到json
字典中,如上所示。将Route
键作为字典的关键字,下游服务的响应体作为值。你可以看到这个对象就是没有任何缩进空格的JSON。
来自下游服务相应的所有头部都会丢失。
Ocelot将总是将聚合请求的内容类型返回application/json
。
如果下游服务返回404
,那么聚合将为该下游服务返回空内容。 即使所有下游都返回404
,它也不会是聚合响应为404
。
疑难杂症 / 更多信息
您不能将Routes
与特定的RequestIdKeys
一起使用,因为这将使跟踪非常的复杂。
聚合仅支持GET HTTP动词。