Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Junior: питання на співбесіді з теми «Документація й контракти»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

5 питань

OpenAPI (раніше Swagger) - стандартний машиночитний формат опису HTTP API у YAML чи JSON: ендпойнти, параметри, тіла запитів і відповідей, коди статусу, автентифікація.

openapi: 3.1.0
info:
  title: Vacancies API
  version: 1.0.0
paths:
  /vacancies/{id}:
    get:
      summary: Отримати вакансію
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: integer }
      responses:
        '200':
          description: Вакансія
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Vacancy' }
        '404':
          description: Не знайдено
components:
  schemas:
    Vacancy:
      type: object
      required: [id, title]
      properties:
        id: { type: integer }
        title: { type: string }
        salary_from: { type: [integer, 'null'] }

Що дає специфікація, крім документації:

  • інтерактивна документація - Swagger UI, Redoc, Scalar, Stoplight Elements з кнопкою «спробувати запит»;
  • генерація клієнтів - типізовані SDK для TypeScript, PHP, мобільних застосунків;
  • моки - фронтенд працює з фейковим сервером до готовності бекенду;
  • тести й валідація - перевірка, що реальні відповіді відповідають опису;
  • лінтинг - автоматична перевірка стилю й помилок у дизайні;
  • виявлення змін, що ламають клієнтів, - порівняння версій специфікації в CI;
  • імпорт у Postman, Insomnia, Bruno, API-шлюзи.

Версії:

  • 3.0 - найпоширеніша в старих інструментах;
  • 3.1 (2021) - повна сумісність із JSON Schema 2020-12;
  • 3.2 (вересень 2025) - зворотно сумісне розширення 3.1: потокові медіатипи (SSE, JSON Lines), нові поля для тегів, метод QUERY тощо.

Для нових проєктів - 3.1 чи 3.2, з перевіркою, що потрібні інструменти їх підтримують.

Головна цінність - єдине джерело правди про контракт між бекендом і клієнтами, замість вікі-сторінок, які розходяться з кодом через тиждень.

У Laravel специфікацію найчастіше генерують з коду (Scramble, Scribe), а не пишуть вручну.

Докладніше в документації: Специфікація OpenAPI 3.2.0

Code-first - спершу пишеться код, специфікація генерується з нього (атрибутами, аналізом коду):

контролери й ресурси Laravel  →  Scramble/Scribe  →  openapi.json  →  документація

Design-first - спершу пишеться специфікація (контракт), її обговорюють і погоджують, а потім за нею пишуть код і клієнтів:

openapi.yaml (рев'ю)  →  моки для фронтенду  →  реалізація бекенду  →  перевірка відповідності

Переваги code-first:

  • специфікація не розходиться з кодом - вона з нього й береться;
  • швидкий старт, мало додаткової роботи;
  • зручно для невеликих команд, де бекенд і фронтенд пишуть ті самі люди.

Недоліки code-first:

  • дизайн API формується реалізацією: назви полів і структура відповідей відображають внутрішню модель (колонки таблиць), а не потреби клієнтів;
  • обговорити API можна лише після того, як його написано;
  • генератор бачить не все: деталі на кшталт можливих помилок чи прикладів доводиться доповнювати.

Переваги design-first:

  • контракт - до коду: фронтенд, мобільна команда й партнери погоджують API заздалегідь і працюють паралельно з моками;
  • кращий дизайн: API проєктують з боку споживача, з рев'ю, як код;
  • генерація серверних заготовок і валідація запитів за специфікацією.

Недоліки design-first:

  • специфікацію треба підтримувати вручну - і перевіряти, що реалізація їй відповідає (тести контракту, валідація відповідей у тестах), інакше вона застаріває;
  • більше процесу й інструментів.

Що обирають на практиці:

  • внутрішнє API одного продукту (Laravel + SPA однієї команди) - code-first зі Scramble: мінімум зусиль, завжди актуально;
  • публічне API, партнерські інтеграції, кілька команд-споживачів - design-first або гібрид: дизайн погоджується в специфікації, а згенерована з коду специфікація порівнюється з погодженою в CI;
  • будь-який підхід виграє від лінтингу специфікації і перевірки змін, що ламають клієнтів, у CI.

Докладніше в документації: Документація OpenAPI для початківців

Scramble генерує специфікацію OpenAPI з коду Laravel автоматично, без анотацій над кожним методом. Він аналізує:

  • маршрути - шляхи, методи, параметри маршруту й прив'язку моделей;
  • валідацію - правила з Form Request чи $request->validate() стають описом тіла запиту й параметрів (required|email|max:255 → обов'язковий рядок формату email);
  • відповіді - API-ресурси (JsonResource), повернені моделі, пагінацію, response()->json(...);
  • помилки - 422 для валідації, 404 для прив'язки моделей, 403 для авторизації, 401 для автентифікації.
composer require dedoc/scramble

Після встановлення документація доступна за адресою /docs/api (інтерфейс на основі Stoplight Elements), а сама специфікація - /docs/api.json.

Доповнення там, де аналізу коду недостатньо:

/**
 * Список вакансій.
 *
 * Повертає опубліковані вакансії, найновіші першими.
 */
public function index(IndexVacancyRequest $request)
{
    // ...
}

PHPDoc-коментар стає описом операції. Для складних випадків - атрибути Scramble й розширення.

Що варто налаштувати:

  • доступ: за замовчуванням документація відкрита лише в локальному оточенні, у продакшені доступ визначає gate viewApiDocs;
  • які маршрути документувати (за замовчуванням - з префіксом api);
  • автентифікація: опис схеми (Bearer-токен Sanctum), щоб кнопка «спробувати» працювала;
  • експорт: php artisan scramble:export записує специфікацію у файл - для генерації клієнтів і перевірок у CI.

Альтернатива - Scribe: генерує документацію й колекції Postman, бере опис з анотацій і може робити справжні запити до ендпойнтів, щоб отримати приклади відповідей.

Обмеження автоматичної генерації:

  • точність залежить від коду: динамічні масиви в toArray(), умовна логіка, дані з сервісів можуть описатися неточно - результат треба переглядати;
  • якість опису - на вас: назви полів, приклади, пояснення бізнес-правил генератор не придумає;
  • вбудовані JSON:API-ресурси Laravel 13 - новий формат; варто перевірити, що версія генератора їх підтримує.

Докладніше в документації: Scramble

Laravel має набір перевірок для JSON-відповідей. Головне - обирати перевірку під те, що саме гарантує API.

it('returns a vacancy', function () {
    $vacancy = Vacancy::factory()->create(['title' => 'Laravel Developer', 'salary_from' => 3000]);

    $this->getJson("/api/vacancies/{$vacancy->id}")
        ->assertOk()
        ->assertJsonPath('data.title', 'Laravel Developer')
        ->assertJsonPath('data.salary_from', 3000)
        ->assertJsonStructure([
            'data' => ['id', 'title', 'salary_from', 'company' => ['id', 'name']],
        ]);
});

Основні методи:

Метод Що перевіряє
assertJson([...]) відповідь містить ці дані (інші поля дозволені)
assertExactJson([...]) відповідь дорівнює цьому JSON
assertJsonPath('data.title', '...') значення за шляхом
assertJsonStructure([...]) наявність ключів (без значень)
assertExactJsonStructure([...]) ключі - і жодних зайвих
assertJsonCount(20, 'data') кількість елементів
assertJsonMissingPath('data.password') поля немає
assertJsonValidationErrors(['email']) помилки валідації для полів

Методи запиту: getJson, postJson, patchJson, deleteJson - автоматично додають Accept: application/json, тож помилки валідації приходять як JSON 422, а не редирект.

Що варто перевіряти в API-тестах:

  • контракт: структура відповіді й типи - те, на що покладаються клієнти;
  • приховані поля: assertJsonMissingPath('data.password_hash') - захист від випадкового витоку при зміні ресурсу;
  • коди статусу для кожного сценарію: 201 при створенні, 422 при помилках, 403 для чужого ресурсу, 404 для неіснуючого;
  • авторизацію: запит від іншого користувача (actingAs($stranger)) - найчастіше забута перевірка;
  • пагінацію й фільтри: assertJsonCount, перевірка, що фільтр справді відсікає записи.

Пастки:

  • assertJson не перевіряє відсутність полів - нове випадкове поле в ресурсі тест не помітить. Для захисту контракту - assertExactJsonStructure або перевірка відповідності специфікації OpenAPI;
  • типи: assertJsonPath('data.price', 100) і '100.00' - різні значення; рішення про формат грошей має бути зафіксоване тестом;
  • дати порівнюють у форматі, який віддає API (ISO 8601 з поясом), а не як об'єкти Carbon.

Для складних перевірок - fluent-API assertJson(fn (AssertableJson $json) => ...).

Докладніше в документації: Laravel: тестування JSON API

Згенерований перелік ендпойнтів з параметрами - лише довідник. Розробник, що інтегрується з API, має відповіді на питання «з чого почати» і «що робити, коли щось пішло не так».

1. Швидкий старт: як отримати ключ, перший запит, який можна скопіювати й виконати за хвилину:

curl https://api.example.com/v1/vacancies?city=kyiv \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

2. Автентифікація: як отримати й оновити токен, термін дії, області доступу (scopes).

3. Приклади - для кожного запиту й відповіді. Реалістичні дані, а не "string" і 0. В OpenAPI - поля example/examples у схемах і медіатипах. Кілька прикладів для різних сценаріїв (вакансія із зарплатою і без).

4. Помилки - не менш детально, ніж успіх:

  • формат помилки (Problem Details чи власний) з прикладами;
  • коди помилок бізнес-логіки й що з ними робити (insufficient_balance - поповнити рахунок);
  • які помилки тимчасові й можна повторити (429, 503), а які ні.

5. Загальні правила API - один раз для всіх ендпойнтів:

  • пагінація, фільтрація, сортування;
  • формати дат, грошей, ідентифікаторів;
  • ліміти частоти й заголовки, що їх показують;
  • ідемпотентність і повтори;
  • версіонування й політика змін.

6. Сценарії (гайди): типові задачі, що складаються з кількох запитів - «створити замовлення й оплатити», «синхронізувати каталог». Довідник ендпойнтів їх не пояснює.

7. Журнал змін (changelog) і дати застарівання.

8. SDK і колекції: офіційні клієнти, колекція Postman/Bruno, посилання на специфікацію OpenAPI для генерації власних клієнтів.

Якість, яку легко перевірити:

  • новий розробник робить перший успішний запит без запитань до команди;
  • кожен ендпойнт має приклад відповіді й перелік можливих помилок;
  • приклади в документації перевіряються автоматично (контрактні тести, валідація за специфікацією) - інакше вони застаріють першими.

Інтерактивність: кнопка «спробувати» в документації (Swagger UI, Scalar, Stoplight Elements) з тестовим оточенням (sandbox) пришвидшує інтеграцію - але ніколи з продакшен-даними.

Докладніше в документації: Документація OpenAPI для початківців