I'm designing microservice architecture as below:
Gateway uses Ocelot to forward requests. I would like to change the body in request received from mobile device on gateway side and add inside the body new GUID. Microservices uses CQRS pattern, so command shouldn't returns anything. I implemented custom middleware to change DownstreamContext:
public override async Task Execute(DownstreamContext context)
{
var secondRequest = JObject.Parse(await context.DownstreamRequest.Content.ReadAsStringAsync());
secondRequest["token"] = "test";
secondRequest["newId"] = Guid.NewGuid();
context.DownstreamRequest.Content = new StringContent(secondRequest.ToString(), Encoding.UTF8);
await this.Next(context);
}
I debugged this and content of DownstreamRequest before call await this.Next(context); is changed, but request incoming to microservice is not changed. Is there any way to change request in gateway and forward this request to microservice in a changed form?
You can use for it a custom middleware
public class SetGuidMiddleware
{
private readonly RequestDelegate _next
public SetGuidMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (!HttpMethods.IsGet(context.Request.Method)
&& !HttpMethods.IsHead(context.Request.Method)
&& !HttpMethods.IsDelete(context.Request.Method)
&& !HttpMethods.IsTrace(context.Request.Method)
&& context.Request.ContentLength > 0)
{
//This line allows us to set the reader for the request back at the beginning of its stream.
context.Request.EnableRewind();
var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
var bodyAsText = Encoding.UTF8.GetString(buffer);
var secondRequest = JObject.Parse(bodyAsText);
secondRequest["token"] = "test";
secondRequest["newId"] = Guid.NewGuid();
var requestContent = new StringContent(secondRequest.ToString(), Encoding.UTF8, "application/json");
context.Request.Body = await requestContent.ReadAsStreamAsync();
}
await _next(context);
}
}
and use it before Ocelot
app.UseMiddleware<SetGuidMiddleware>();
app.UseOcelot().Wait();