我正在设计如下的微服务架构:
网关使用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);。被更改,但传入微服务的请求未更改。有什么方法可以在网关中更改请求并将此请求以更改后的形式转发给微服务?
您可以为此使用自定义中间件
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();