Diketik HttpClient vs IHttpClientFactory

Apakah ada perbedaan antara 2 skenario pengaturan HttpClient berikut?

Haruskah saya memilih yang satu dibandingkan yang lain?

Klien yang diketik:

public class CatalogService 
{
    private readonly HttpClient _httpClient;
    
    public CatalogService(HttpClient httpClient) {
        _httpClient = httpClient;
    }
    
    public async Task<string> Get() {
        var response = await _httpClient.GetAsync();
        ....
    }
    
    public async Task Post() {
        var response = await _httpClient.PostAsync();
        ...
    }
}
// Startup.cs
//Add http client services at ConfigureServices(IServiceCollection services)
services.AddHttpClient<ICatalogService, CatalogService>();

Pabrik Klien IHttp:

public class CatalogService 
{
    private readonly IHttpClientFactory _factory;
    
    public CatalogService(IHttpClientFactory factory) {
        _factory = factory;
    }
    
    public async Task<string> Get() {
        var response = await _factory.CreateClient().GetAsync();
        ....
    }
    
    public async Task Post() {
        var response = await _factory.CreateClient().PostAsync();
        ...
    }
}
// Startup.cs
//Add http client services at ConfigureServices(IServiceCollection services)
services.AddHttpClient();
```

person Ivan Studenikin    schedule 09.10.2020    source sumber
comment
Apakah ini menjawab pertanyaan Anda? HttpClientFactory.Create vs HttpClient baru   -  person Julian    schedule 09.10.2020
comment
@Julian, tidak, karena ini tentang HttpFactory lama   -  person Ivan Studenikin    schedule 13.10.2020


Jawaban (3)


IMO, saya akan pergi dengan melewati HttpClient. Alasannya adalah,

  1. Prinsip KISS - Yang benar-benar dibutuhkan CatalogService adalah HttpClient. Layanan tidak peduli tentang cara mendapatkan klien.
  2. Single Responsibility Principle (SRP) - Say tomorrow you have to keep two instances of CatalogService to send requests to two different endpoints,
    • You can pass in a IHttpClientFactory and implement routing inside CatalogService, but that breaks SRP.
    • Atau, Anda dapat membuat CatalogServiceFactory. Pabrik itu menerima IHttpClientFactory dan mengimplementasikan perutean di dalamnya. Hal ini juga dikenal sebagai Pemisahan Kekhawatiran.
person Han Zhao    schedule 10.10.2020

Saya pikir perbedaan terbesar terlihat ketika Anda melihatnya dari sudut pandang konsumsi.

Klien yang diketik

Anda akan menerima instance HttpClient, yang mungkin telah dihiasi dengan beberapa strategi tangguh terhadap kegagalan sementara dan dengan beberapa nilai default. Anda bahkan mungkin menerima klien yang BaseUrl sudah disetel.

Jadi, pendekatan ini bisa sangat berguna jika Anda perlu menyembunyikan klien REST API di balik lapisan layanan yang diketik dengan kuat.

Klien bernama

Teknik ini dapat berguna ketika Anda memerlukan beberapa contoh dari klien tertentu atau ketika Anda memerlukan beberapa klien berbeda. Jika Anda telah mendaftarkan beberapa klien berbeda dengan nama berbeda maka Anda dapat mengambilnya dengan mudah melalui satu API.

Jadi, pendekatan ini dapat berguna jika Anda perlu memanggil sistem hilir yang berbeda dan Anda perlu menggabungkan hasilnya.

Senang membaca artikel

person Peter Csala    schedule 12.10.2020

Memiliki abstraksi (yaitu IHttpClient) jauh lebih baik dan lebih dipuji oleh masyarakat. Ini memungkinkan Anda untuk menetapkan HttpClient serta IHttpClient yang ditulis khusus tanpa pernah mengubah CatalogService.

Ini adalah poin yang sangat penting ketika membuat sistem besar karena ketergantungan Anda pada implementasi konkret berkurang, begitu pula biaya pemeliharaannya.

Selain itu, penggunaan abstraksi memungkinkan menunjukkan penggunaan apa yang sebenarnya dimaksudkan dan mengurangi kemungkinan gangguan. Salah satu contoh:

public interface MyInterface
{
    void UsefulMethod();
}

public class MyClass : MyInterface
{
    public float variable1;
    public float moreBurden;
    public float thisIsNotRequiredAtAll;

    public void UsefulMethod() {}
    public void AnotherMethod() {}
    public void MoreNoiseMethod() {}
}

public class MyService
{
    private MyClass _myClass;

    public MyService(MyClass myClass)
    {
        _myClass = myClass;
    }

    public void MyOnlyMethod()
    {
        _myClass.UsefulMethod();
    }
}

Dalam hal ini, Anda hanya menggunakan satu metode, namun layanan Anda dapat mengakses banyak informasi yang tidak perlu, sehingga mengganggu tujuan. Dan untuk membuat MyService, pembuatnya harus bisa membuat instance MyClass.

Sekarang gambar MyService ditulis seperti

public class MyService
{
    private IMyInterface _myInterface;

    public MyService(IMyInterface myInterface)
    {
        _myInterface = myInterface;
    }
   
    public void MyOnlyMethod()
    {
        _myInterface.UsefulMethod();
    }
}

Sekarang, tujuan _myInterface sudah jelas - Anda hanya memerlukan subset metode tertentu. MyService hanya memiliki akses ke satu metode tersebut dan tidak terganggu oleh semua kemungkinan detail implementasi.

person tsvedas    schedule 09.10.2020
comment
Meskipun semua ini mungkin benar, firasat saya adalah Anda melewatkan inti pertanyaan operasi - person TheGeneral; 10.10.2020
comment
Yup salahku, aku ketinggalan itu IHttpClientFactory bukan IHttpClient... - person tsvedas; 10.10.2020