Warm tip: This article is reproduced from stackoverflow.com, please click
.net c# microservices ocelot

Ocelot

发布于 2020-03-28 23:14:23

I'm designing microservice architecture as below:

Microservice architecture

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?

Questioner
Lutz Harrold
Viewed
117
Roman Marusyk 2020-01-31 17:37

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();