You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Typed HTTP Client应归属至应用架构的哪一层?

类型化HTTP客户端应置于哪一层?

现有架构层级

  • Web API:为外部调用提供应用接入点
  • 基础设施层(Infrastructure):提供数据库访问仓储
  • 服务层(Service Layer):负责各类业务用例(如「添加商品至购物车」)
  • 领域层(Domain):包含带业务逻辑的领域对象

架构层级引用关系可参考下图:
架构层级图示

我希望添加一个类型化HTTP客户端,用于从外部API获取特定信息,想请教该客户端应创建在哪一层/项目中?

我的现有思路

我最初考虑放在基础设施层,但基础设施层依赖于需要API数据的服务层,这意味着要在API之上引入接口,同时类型化HTTP客户端的响应对象必须定义在基础设施层,这开始变得混乱。

这种情况下会面临两种选择:
A) 服务层直接依赖API响应对象;
B) 类型化HTTP客户端将响应映射为服务层定义的对象。

这意味着要么引入不必要的依赖,那还不如把所有内容都放在服务层;要么让类型化HTTP客户端承担更多职责,这感觉像是代码异味。


最佳实践建议

类型化HTTP客户端本质是外部资源的访问实现,和数据库仓储属于同一类基础设施组件,因此更适合放在基础设施层。但需要通过依赖倒置原则解决你提到的依赖问题,具体方案如下:

  1. 定义抽象接口:在服务层(或独立的抽象层)定义一个用于获取外部数据的抽象接口,比如 IExternalDataService,接口中声明所需的业务方法(而非HTTP调用细节),方法参数和返回值使用领域层/服务层定义的业务对象。

  2. 实现类型化客户端:在基础设施层创建类型化HTTP客户端,并让它实现服务层定义的抽象接口。在实现中处理HTTP调用、响应解析,并将外部API的响应对象映射为服务层需要的业务对象。

这样做的核心优势:

  • 遵循依赖倒置:服务层仅依赖抽象接口,不直接依赖基础设施层的实现,避免了反向依赖问题;
  • 职责清晰:类型化客户端专注于HTTP通信和外部数据适配,服务层专注于业务用例逻辑;
  • 可测试性:服务层可以通过Mock抽象接口进行单元测试,无需调用真实外部API。

举个简单代码示例:

  • 服务层抽象接口:
public interface IProductInfoService
{
    Task<ProductDetails> GetProductDetailsAsync(string productId);
}
  • 基础设施层类型化客户端实现:
public class ExternalProductApiClient : IProductInfoService
{
    private readonly HttpClient _httpClient;

    public ExternalProductApiClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<ProductDetails> GetProductDetailsAsync(string productId)
    {
        var response = await _httpClient.GetFromJsonAsync<ExternalProductResponse>($"products/{productId}");
        // 映射外部响应到业务对象
        return new ProductDetails
        {
            Id = response.Id,
            Name = response.ProductName,
            Price = response.Price.Amount
        };
    }
}
  • 依赖注册(在Startup/Program.cs中):
builder.Services.AddHttpClient<IProductInfoService, ExternalProductApiClient>(client =>
{
    client.BaseAddress = new Uri("https://external-api.example.com/");
});

这种方式既保留了基础设施层处理外部资源的职责,又避免了你的两种顾虑:服务层不需要依赖外部API的响应对象,类型化客户端的映射职责属于基础设施层的合理范围(负责与外部系统的适配),不属于代码异味。

内容的提问来源于stack exchange,提问作者Jakob Busk Sørensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:35:41