ASP.NET Web API如何透传内部API响应避免大负载序列化性能损耗
问题描述
当前使用的架构包含两个互联的API:面向客户端暴露的External API,以及对接内部服务、仅对External API开放的Internal API。
External API需要将Internal API返回的响应数据直接透传给客户端,无需额外处理,之前暂未找到合适实现方案,当前采用的是对返回对象做反序列化后再重新序列化输出的逻辑。
该实现的问题在于,当JSON负载超过15MB时,External API的处理耗时会显著上升,这部分开销全部来自JSON反序列化操作。
本文要解决的核心需求是:找到可以直接返回原始JSON结果,无需对响应内容做序列化/反序列化处理的方案。
现有实现代码
External API 控制器
[HttpGet] public async Task<ActionResult> GetSomeData(...) { var serviceResponse = await _serviceInvoker.GetAsync<SomeType>(...) .ConfigureAwait(false); Response.StatusCode = (int)serviceResponse.StatusCode; return new JsonResult(serviceResponse.Content); }
内部服务调用器响应解析逻辑
using System.Text.Json; private async Task<ServiceInvokerResult> ParseServiceResponse<T>(HttpResponseMessage response) { object deserializedContent = null; var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); switch (response.StatusCode) { case HttpStatusCode.OK: deserializedContent = JsonSerializer.Deserialize<T>(content); break; (...) } return new ServiceInvokerResult { (...) StatusCode = response.StatusCode, Content = deserializedContent ?? content }; }
最终解决方案
调整ServiceInvoker实现,使其直接返回未经处理的HttpResponseMessage,避免多余的序列化、反序列化操作:
优化后的External API控制器
[HttpGet] public async Task<ActionResult> GetSomeData(...) { var serviceResponse = await _serviceInvoker.GetAsync(...) .ConfigureAwait(false); Response.StatusCode = (int)serviceResponse.StatusCode; return new FileStreamResult(await response.GetContentAsStreamAsync(), response.GetContentType()); }
新增扩展方法
public static async Task<Stream> GetContentAsStreamAsync(this HttpResponseMessage response) { return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); } public static string GetContentType(this HttpResponseMessage response) { return response.Content?.Headers?.ContentType?.MediaType ?? Constants.Http.JsonContentType; }
内容的提问来源于stack exchange,提问作者mugen
相关产品推荐
相关产品推荐

