Ось готовий урок, створений спеціально для тебе у стилі David Malan. Ми зануримося в тему, розберемо її «на атомах» і зберемо знову.
Приготуй свій редактор коду (будемо використовувати C#/.NET як стандарт для класу HttpClient, але логіка універсальна).
🎓 Урок CS50: HttpClient та магія REST API
Привіт, друзі! Це CS50.
Сьогодні ми виходимо за межі нашого локального комп'ютера. До цього моменту ваші програми жили ніби в вакуумі: вони працювали з тими даними, які ви вводили руками, або читали з локального файлу.
Але погляньте на свій смартфон. Instagram, Uber, Погода — чи корисні були б ці програми, якби вони не мали доступу до Інтернету? Абсолютно ні. Вони були б просто красивими картинками.
Сьогодні ми навчимо ваш код спілкуватися зі світом.
1. 🔥 Вступ: Проблема «мовчазного» коду
Уявіть, що ви пишете програму для відстеження курсів валют.
Ви можете створити змінну double dollarRate = 38.5;.
Але що станеться завтра? Курс зміниться. Вам доведеться відкривати код, змінювати число, перекомпілювати програму і розсилати оновлення всім користувачам. Це абсурд, правда?
Світ змінюється щосекунди. Ваша програма має отримувати актуальні дані ззовні — з серверів банку, біржі чи прогнозу погоди.
Питання до вас: Як, власне, ваш код (який є просто текстом на вашому диску) може "постукати" у двері сервера Google або НБУ і сказати: "Гей, дай мені актуальні дані"?
Нам потрібен посередник. Нам потрібен кур'єр. Нам потрібен HttpClient.
Аналогія: Уявіть, що REST API (сервер) — це кухня ресторану. Там є продукти (дані). Ви (ваш код) — це клієнт за столиком. Ви не можете просто забігти на кухню і почати смажити собі м'ясо (це небезпечно). Вам потрібен офіціант. Ви кажете офіціанту: "Принесіть мені меню" (GET-запит). Офіціант йде на кухню, бере меню і повертається до вас.
HttpClient — це і є ваш офіціант.
2. 🧠 Теоретична база: Що "під капотом"?
Перш ніж писати код, розберемося з правилами етикету цього ресторану. Це називається HTTP-протокол.
Коли HttpClient стукає до сервера, він не просто кричить. Він використовує конкретні команди (ми називаємо їх дієсловами або методами):
- GET — "Дай мені це" (Отримати список товарів, погоду, профіль).
- POST — "Тримай, це нове" (Створити нового користувача, відправити замовлення).
- PUT — "Онови це повністю" (Змінити дані товару).
- DELETE — "Видали це" (Видалити коментар).
⚙️ Як це працює технічно?
- Request (Запит): Ваш
HttpClientформує пакет. У ньому є адреса (URL), метод (GET/POST) і іноді "тіло" (дані, які ви передаєте). - Network: Цей пакет летить дротами через океани.
- Response (Відповідь): Сервер обробляє запит і повертає відповідь.
Що треба запам'ятати залізно: Відповідь сервера завжди містить Status Code (Код стану). Це як світлофор: * 🟢 200 OK — Все супер, ось твої дані. * 🔴 404 Not Found — Такого ресурсу немає (помилка в адресі). * 🔴 500 Internal Server Error — Сервер зламався (це не ваша вина, а їхня).
Інтуїтивно зрозумійте:
Операції в мережі — повільні. Комп'ютер робить мільярд операцій за секунду, а запит в мережу може йти цілу секунду. Для процесора це вічність! Тому ми будемо використовувати асинхронність (await), щоб програма не "зависала", поки офіціант йде на кухню.
3. 🧪 Приклади: Від Hello World до реальності
Для прикладів використаємо C#, бо там HttpClient — це стандарт. Але в Python (requests) чи JS (fetch) логіка ідентична.
Приклад 1: Простий GET-запит (Забираємо вміст сайту)
Уявіть, що ви хочете скачати головну сторінку Google.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
// Створюємо офіціанта (HttpClient)
// Увага: в реальних проєктах ми робимо це трохи інакше, але про це згодом.
static readonly HttpClient client = new HttpClient();
static async Task Main()
{
try
{
// 1. Формуємо запит
Console.WriteLine("Стукаємо до Google...");
// "await" означає: "Почекай тут, поки дані не прийдуть, але не блокуй комп'ютер"
HttpResponseMessage response = await client.GetAsync("https://www.google.com");
// 2. Перевіряємо, чи все ок (чи код 200?)
response.EnsureSuccessStatusCode();
// 3. Читаємо тіло відповіді як рядок
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Отримано символів: {responseBody.Length}");
// Console.WriteLine(responseBody); // Якщо хочете побачити HTML-код
}
catch (Exception e)
{
Console.WriteLine($"Ой! Щось пішло не так: {e.Message}");
}
}
}
Питання до студента: Як ви думаєте, що станеться, якщо я вимкну Wi-Fi і запущу цей код?
(Відповідь: Програма викине виключення (Exception), бо не зможе достукатися до сервера. Тому блок try-catch обов'язковий!)
Приклад 2: Робота з JSON (Реальний сценарій)
Ніхто не читає сирий HTML. Програми обмінюються даними у форматі JSON (текстовий формат, схожий на об'єкти).
Давайте отримаємо випадковий цікавий факт про котів з відкритого API: https://catfact.ninja/fact
Очікування: Ми отримаємо рядок типу {"fact":"Cats adhere to the 3-second rule.","length":32}. Нам треба перетворити це на C# об'єкт.
using System.Net.Http.Json; // Потрібна ця бібліотека для магії
// Створюємо клас, який виглядає як наш очікуваний JSON
public class CatFact
{
public string Fact { get; set; }
public int Length { get; set; }
}
// ... всередині методу Main ...
// Робимо запит і одразу перетворюємо JSON на об'єкт CatFact (Десеріалізація)
CatFact fact = await client.GetFromJsonAsync<CatFact>("https://catfact.ninja/fact");
Console.WriteLine($"😺 ФАКТ ПРО КОТІВ: {fact.Fact}");
Чому це круто? Ви не парсите текст вручну. Ви просто кажете: "Ось посилання, ось мій клас, зроби магію".
4. 🛠 Практична частина
Час закачати рукави. Виконайте ці завдання по черзі:
- 🔹 Повтори та відчуй: Запусти код з прикладу про котів. Запусти його 3 рази. Чи різні факти приходять?
- 🔹 Зламай систему: Зміни URL на
https://catfact.ninja/abracadabra. Яку помилку ти отримаєш? Оброби її так, щоб програма писала "На жаль, коти зараз зайняті" замість страшного системного тексту помилки (використайtry-catchабо перевіркуresponse.StatusCode). - 🔹 Crypto-Check: Знайди відкрите API для курсу біткоїна (наприклад, CoinGecko або Coindesk). Напиши програму, яка виводить поточну ціну BTC у доларах.
- Підказка: Тобі доведеться створити клас, який відповідає структурі JSON цього API.
- 🔹 А що, якщо... (Міні-кейс): Напиши консольну програму, яка запитує у користувача ім'я (наприклад, "Ivan") і використовує API
https://api.agify.io?name=Ivan, щоб передбачити вік цієї людини. Виведи результат: "Іване, штучний інтелект думає, що тобі 45 років".
5. 💡 Мислення як у розробника
Ось тут ми відділяємо новачків від профі.
❌ Типова помилка новачка:
Створювати новий HttpClient всередині кожного методу або циклу.
// ТАК НЕ РОБИТИ!
for(int i=0; i<10; i++) {
using(var client = new HttpClient()) { ... }
}
Чому? Кожен HttpClient відкриває мережевий порт. Якщо ви закриєте його, порт залишається "зайнятим" системою ще деякий час. Якщо ви зробите так 1000 разів поспіль, у вашого комп'ютера закінчаться вільні порти (Socket Exhaustion), і програма впаде.
✅ Як думає сеньйор:
1. Singleton: HttpClient має бути один на весь додаток (або використовуйте IHttpClientFactory в серйозних ASP.NET проєктах). Він створений, щоб жити довго і перевикористовуватися.
2. Не довіряй мережі: Мережа завжди ламається. Тайм-аути, обриви зв'язку, 500-ті помилки. Хороший розробник завжди пише код так, ніби API може не відповісти.
3. Безпека: Ніколи не "зашивайте" паролі чи API-ключі прямо в код (hardcode). Використовуйте змінні середовища або конфігураційні файли.
6. 🧩 Підсумок
Вітаю! Сьогодні ви зруйнували стіну між вашим кодом і рештою світу.
Що ви тепер вмієте:
1. Розуміти, як спілкуються програми (HTTP, GET, JSON).
2. Використовувати HttpClient для отримання даних.
3. Перетворювати "сирий" JSON на зручні об'єкти.
4. Обробляти базові помилки мережі.
Тепер ваш код може дізнатися погоду, курс акцій, відправити повідомлення в Telegram або завантажити картинку. Ви більше не обмежені своїм жорстким диском.
🤔 Тизер наступного уроку: Ми навчилися брати дані. Але що, якщо ми хочемо зберегти їх назавжди, і не в чужому API, а у себе? Файли — це ненадійно. Наступного разу ми поговоримо про те, де зберігає дані Facebook, Google і банки. Готуйтеся, ми йдемо до Баз Даних та SQL!
А поки що — це був CS50. Побачимось! 👋