Middle: питання на співбесіді з теми «HTTP-клієнт»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
2 питання
$response = Http::connectTimeout(3)
->timeout(10)
->retry([200, 500, 1000], when: fn (Throwable $e) => $e instanceof ConnectionException
|| ($e instanceof RequestException && $e->response->serverError()))
->get($url);
Таймаути:
connectTimeout()- скільки чекати з'єднання (за замовчуванням 10 с);timeout()- скільки чекати відповідь (за замовчуванням 30 с).
30 секунд у веб-запиті - це заблокований воркер PHP. Коли сторонній сервіс зависає, такі запити швидко займають усі воркери, і падає весь сайт. Тому таймаут ставлять під реальну очікувану швидкість сервісу.
Повтори:
retry(3, 100)- три спроби з паузою 100 мс; масив задає паузи окремо (наростання);- третій аргумент
when- що повторювати: збої з'єднання й 5xx так, 4xx - ні (помилка в запиті не виправиться повтором); - після вичерпаних спроб -
RequestException, або остання відповідь зthrow: false.
Обережно з не ідемпотентними запитами: повтор POST /payments після таймауту може створити другий платіж - перший міг пройти. Для таких - ключ ідемпотентності, якщо API його підтримує, або без автоматичних повторів.
У черзі повторами зручніше керувати рівнем завдання (tries, backoff, release() на 429), ніж всередині HTTP-клієнта.
Через Http::fake() - запити не йдуть у мережу, а отримують задані відповіді.
it('imports exchange rates', function () {
Http::preventStrayRequests();
Http::fake([
'api.rates.example/*' => Http::response(['usd' => 41.2, 'eur' => 44.9]),
]);
app(RatesImporter::class)->import();
expect(Rate::where('code', 'usd')->value('value'))->toBe(41.2);
Http::assertSent(fn (Request $r) => $r->hasHeader('Authorization'));
});
Що підміняють:
- конкретні адреси шаблонами з
*; - послідовності:
Http::sequence()->push(...)->pushStatus(500)- перша відповідь успішна, друга з помилкою; - збій з'єднання:
Http::failedConnection(); - логіку: замикання, що повертає відповідь залежно від запиту.
Перевірки запитів: assertSent, assertNotSent, assertSentCount, assertNothingSent.
preventStrayRequests() - будь-який непідмінений запит кидає виняток. Його ставлять у базовому TestCase чи Pest.php: тест, що випадково ходить у справжній API, стає повільним, нестабільним і може щось змінити в чужій системі.
Що обов'язково покрити: не лише успіх, а й 500, таймаут, 429, неочікуваний формат відповіді - саме ці гілки ламаються в продакшені.