Ответ
Да, интенсивно использовал HttpClient. Ключевой момент — правильное управление его жизненным циклом для предотвращения проблем с производительностью, таких как исчерпание сокетов.
Рекомендуемый подход: использовать IHttpClientFactory.
Почему это важно?
Прямое создание и удаление HttpClient в using блоке для каждого запроса может привести к задержкам в освобождении сетевых ресурсов. Фабрика управляет пулом HttpMessageHandler, что решает эту проблему.
Пример настройки и использования через DI:
-
Регистрация в
Startup.cs/Program.cs:// Базовая регистрация builder.Services.AddHttpClient(); // Именованный клиент с конфигурацией builder.Services.AddHttpClient("GitHub", client => { client.BaseAddress = new Uri("https://api.github.com/"); client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); client.Timeout = TimeSpan.FromSeconds(15); }); -
Использование в сервисе:
public class DataService : IDataService { private readonly HttpClient _httpClient; // Инжектируем фабрику public DataService(IHttpClientFactory httpClientFactory) { // Создаем клиент. Его не нужно диспозить. _httpClient = httpClientFactory.CreateClient("GitHub"); } public async Task<User> GetUserAsync(string username) { var response = await _httpClient.GetAsync($"users/{username}"); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize<User>(json); } }
Дополнительные практики:
- Использование
PollyчерезAddHttpClientдля реализации политик повторных попыток и обработки сбоев. - Всегда использовать асинхронные методы (
GetAsync,PostAsync). - Валидация и обработка ответов (проверка
IsSuccessStatusCodeили вызовEnsureSuccessStatusCode()).
Ответ 18+ 🔞
Ага, значит, ты с HttpClient на короткой ноге был, да? Ну, это ж классика, блядь. Все через это проходят. Главная засада — если его как попало юзать, он тебе сокеты все в ноль выжрет, и потом сиди, гадай, почему сервис в асфальт влип.
Что делать, чтобы не облажаться? Юзать IHttpClientFactory. Без вариантов.
А почему, спрашивается? Потому что если ты каждый раз в using его пихаешь и думаешь, что молодец, то на деле получается, что сокеты-то не сразу освобождаются, висят как проклятые. Фабрика же умная — она пул этих самых HttpMessageHandler грамотно держит, и проблем не возникает. Просто красота, ёпта.
Вот как это в деле выглядит, смотри:
-
Прописываем в стартапе (
Startup.csилиProgram.cs):// Самый простой способ — добавил и забыл builder.Services.AddHttpClient(); // А можно и именованного клиента настроить, чтоб не париться потом builder.Services.AddHttpClient("GitHub", client => { client.BaseAddress = new Uri("https://api.github.com/"); client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); client.Timeout = TimeSpan.FromSeconds(15); // Чтобы не ждать до второго пришествия }); -
А вот как этим в сервисе пользоваться:
public class DataService : IDataService { private readonly HttpClient _httpClient; // Просто просим фабрику, она нам всё даст public DataService(IHttpClientFactory httpClientFactory) { // Берём клиента. И НЕ ДИСПОЗИМ ЕГО, запомни! Фабрика сама всё разрулит. _httpClient = httpClientFactory.CreateClient("GitHub"); } public async Task<User> GetUserAsync(string username) { var response = await _httpClient.GetAsync($"users/{username}"); response.EnsureSuccessStatusCode(); // На всякий пожарный, чтоб не проёбывать ошибки var json = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize<User>(json); } }
И ещё пару советов на дорожку, а то мало ли:
- Через
AddHttpClientможноPollyприкрутить — для повторных попыток и отказоустойчивости. Очень полезная штука, когда сеть глючит. - Только асинхронные методы, блядь,
GetAsync,PostAsync. Не надо тут синхронных вызовов, это же 2024 год на дворе. - Всегда смотри, что тебе в ответ пришло. Либо
IsSuccessStatusCodeпроверь, либоEnsureSuccessStatusCode()кинь, чтобы не гадать, почему данные не пришли, а сервис уже в нокауте.