I'm implementing custom Aggregator using Ocelot in ASP.NET it's throwing error in Startup.cs Ocelot middleware. However, both Microservices are working fine and fetching the data independently.
When I'm calling them from my API Gateway it's throwing below error.
Startup.cs
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()
.AddSingletonDefinedAggregator<MyAggregator>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
await app.UseOcelot();
}
}
Here is my ocelot.json file for routes of different Microservices.
ocelot.json
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/user/getUser",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "44378"
}
],
"UpstreamPathTemplate": "/getUser",
"Key": "User"
},
{
"DownstreamPathTemplate": "/product/getProduct",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "44357"
}
],
"UpstreamPathTemplate": "/getProduct",
"Key": "Product"
}
],
"Aggregates": [
{
"ReRouteKeys": [
"User",
"Product"
],
"UpstreamPathTemplate": "/UserAndProduct"
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5000/"
}
}
My custom aggregator class
MyAggregator.cs
public class MyAggregator : IDefinedAggregator
{
public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
{
var one = await responses[0].Items.DownstreamResponse().Content.ReadAsStringAsync();
var two = await responses[1].Items.DownstreamResponse().Content.ReadAsStringAsync();
var contentBuilder = new StringBuilder();
contentBuilder.Append(one);
contentBuilder.Append(two);
var stringContent = new StringContent(contentBuilder.ToString())
{
Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
};
return new DownstreamResponse(stringContent, HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "OK");
}
}
You forgot to mention your custom aggregator in your
ocelot.json
file. Ocelot needs to know your custom aggregator whenever you hit/UserAndProduct
.And there is a breaking change in ocelot's latest version. Use the key
Routes
instead ofReRoutes
. You can use the following json file.