从 HttpClient 响应中注入 headers 的自定义中间件
Custom middleware to inject headers from HttpClient response
我正在构建一种 API 网关。
用户向我的 API 发送数据,我请求一个内部服务器提供一些数据,然后我将其发回给用户。
我的问题是我应该从 HttpClient 响应中获取一些 headers 并将其发送回客户端,这很简单,例如:
var response = await _httpClient.Client.GetAsync($"route" + query);
var responseBodyAsJson = HttpClientHelper.ExtractGenericJsonDocument(await response.Content.ReadAsStringAsync());
var cache = HttpClientHelper.ExtractCacheControl(response.Headers.CacheControl.ToString());
HttpContext.Response.Headers.Add(cache);
return responseBody;
这已经在工作了,我删除了修改 json 响应的部分,并读取了其他一些 headers。
但是现在有 10 个控制器路由,以后会添加更多。我不想一直写所有这些,而且将来有人可能会更改它而忘记 headers.
我试过做这样的中间件:
public async Task InvokeAsync(HttpContext context)
{
string cacheHeader = context.Request.Headers.TryGetValue("cache-control", out var values) ? values.FirstOrDefault() : null;
var cache = HttpClientHelper.ExtractCacheControl(cacheHeader);
context.Response.Headers.Add(cache);
await _next(context);
}
但是我意识到中间件可以访问的上下文是我手动注入 headers 的上下文。
那么,有没有一种方法可以读取 HttpClient 上下文响应并将其写入整个 app/path/controller 的 API 响应?
好吧,可能是我表达的不对,中间件的思路不行,连_next的位置都改了。
不过没问题,换个方式就可以了。
我用 IHttpContextAccessor 在我的 HttpClient class 中做了一个 DI。
请记住,您需要在启动时将其添加为单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
他们在我的 HttpClient class 中的新 public 方法中做了类似的事情:
_httpContextAccessor.HttpContext.Response.Headers.Add(cache);
最后我的端点结束得更干净了,比如:
var response = await _httpClient.PrivateGetJsonAndInjectHeader($"route" + query);
return responseBody;
结果并不是真正的“SOLID”,因为我的新 PrivateGetJsonAndInjectHeader 获取数据,return 数据,还修改了主上下文 Headers,但仍然更清晰,并且应该避免任何错误。如果需要,将来也更容易修改。
我正在构建一种 API 网关。
用户向我的 API 发送数据,我请求一个内部服务器提供一些数据,然后我将其发回给用户。
我的问题是我应该从 HttpClient 响应中获取一些 headers 并将其发送回客户端,这很简单,例如:
var response = await _httpClient.Client.GetAsync($"route" + query);
var responseBodyAsJson = HttpClientHelper.ExtractGenericJsonDocument(await response.Content.ReadAsStringAsync());
var cache = HttpClientHelper.ExtractCacheControl(response.Headers.CacheControl.ToString());
HttpContext.Response.Headers.Add(cache);
return responseBody;
这已经在工作了,我删除了修改 json 响应的部分,并读取了其他一些 headers。
但是现在有 10 个控制器路由,以后会添加更多。我不想一直写所有这些,而且将来有人可能会更改它而忘记 headers.
我试过做这样的中间件:
public async Task InvokeAsync(HttpContext context)
{
string cacheHeader = context.Request.Headers.TryGetValue("cache-control", out var values) ? values.FirstOrDefault() : null;
var cache = HttpClientHelper.ExtractCacheControl(cacheHeader);
context.Response.Headers.Add(cache);
await _next(context);
}
但是我意识到中间件可以访问的上下文是我手动注入 headers 的上下文。
那么,有没有一种方法可以读取 HttpClient 上下文响应并将其写入整个 app/path/controller 的 API 响应?
好吧,可能是我表达的不对,中间件的思路不行,连_next的位置都改了。 不过没问题,换个方式就可以了。
我用 IHttpContextAccessor 在我的 HttpClient class 中做了一个 DI。 请记住,您需要在启动时将其添加为单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
他们在我的 HttpClient class 中的新 public 方法中做了类似的事情:
_httpContextAccessor.HttpContext.Response.Headers.Add(cache);
最后我的端点结束得更干净了,比如:
var response = await _httpClient.PrivateGetJsonAndInjectHeader($"route" + query);
return responseBody;
结果并不是真正的“SOLID”,因为我的新 PrivateGetJsonAndInjectHeader 获取数据,return 数据,还修改了主上下文 Headers,但仍然更清晰,并且应该避免任何错误。如果需要,将来也更容易修改。