Ocelot - Изменение тела запроса в восходящем направлении в шлюзе не вызывает изменений в запросе в нисходящем направлении - PullRequest
2 голосов
/ 28 января 2020

Я проектирую микросервисную архитектуру, как показано ниже:

Microservice architecture

Шлюз использует Ocelot для пересылки запросов. Я хотел бы изменить тело в запросе, полученном от мобильного устройства на стороне шлюза, и добавить в тело новый GUID. Микросервисы используют шаблон CQRS, поэтому команда не должна ничего возвращать. Я реализовал пользовательское промежуточное ПО для изменения 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);
    }

Я отладил это и содержимое DownstreamRequest перед вызовом и ожидаем this.Next (context); изменяется, но входящий запрос в микросервис не изменяется. Есть ли способ изменить запрос в шлюзе и переслать этот запрос в микросервис в измененном виде?

1 Ответ

2 голосов
/ 31 января 2020

Вы можете использовать для него пользовательское промежуточное ПО

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

и использовать его до Ocelot

app.UseMiddleware<SetGuidMiddleware>();
app.UseOcelot().Wait();
...