Ocelot
Ocelot copied to clipboard
Aggregators : allow sequential calls
Expected Behavior / New Feature
Currently when using the query aggregators all the calls merge synchronously. In some cases it may be interesting to ensure that these calls are made synchronously:
- the result of request 1 is retrieved
- then, after a possible business processing, it is added to the parameters of the request 2 I made the change on a personal fork, it is quite easy to set up (I started from the principle that by default the parameters are pre-filled identically for all requests. Here is an example of use:
override public async Task<DownstreamResponse> Aggregate(List<HttpContext> contexts, RequestDelegate next = null)
{
if (!sequential)
{
await FireAll(contexts, next);
var response1 = GetResponse(contexts[0]);
var result1 = await GetResult<ExampleApiMessage>(response1);
var response2 = GetResponse(contexts[1]);
var result2 = await GetResult<ExampleData>(response2);
var result = new AggregateData(result1, result2);
return Return(result);
}
else
{
await Fire(contexts[0], next);
var response1 = GetResponse(contexts[0]);
var result1 = await GetResult<ExampleApiMessage>(response1);
SetQueryString(contexts[1], new QueryString("?id=4¶meter=" + result1.message));
await Fire(contexts[1], next);
var response2 = GetResponse(contexts[1]);
var result2 = await GetResult<ExampleData>(response2);
var result = new AggregateData(result1, result2);
return Return(result);
}
}
As soon as calls become sequential, it becomes interesting to allow POST-type requests on aggregators. So I also removed this limitation. Here is an example of using with an aggregator with POST and GET:
override public async Task<DownstreamResponse> Aggregate(List<HttpContext> contexts, RequestDelegate next = null)
{
// Get request body
// dynamic body = await GetBodyAsDynamic(contexts[0]);
var body = await GetBodyAsDictionary(contexts[0]);
SetQueryString(contexts[0], new QueryString("?test=" + body["paramForGet"]));
await Fire(contexts[0], next, "GET");
var response1 = GetResponse(contexts[0]);
var result1 = await GetResult<ExampleApiMessage>(response1);
// Refactor body and refresh request
body.Remove("paramForGet");
body.Add("param2", result1.message);
SetBody(contexts[1], body);
// Fire post request
await Fire(contexts[1], next, "POST");
var response2 = GetResponse(contexts[1]);
var result2 = await GetResult<DefaultApiMessage>(response2);
return Return(result2);
}
My code is not very sexy I admit it because I made sure that there is the least code that differs from the original. I think that ideally there should be more automatic things via the configuration server.
Actual Behavior / Motivation for New Feature
Remove a very strong limitation of Ocelot
+1
Hi @cfeltz34 ! Thanks for your interest in Ocelot!
Will you contribute and develop this feature?