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

Питання на співбесіді: API

Найпопулярніші питання з реальних Laravel/PHP співбесід для всіх рівнів

5 питань

Найпростіше - повернути масив або модель: Laravel сам віддасть JSON із правильним заголовком.

public function show(Post $post)
{
    return $post;                       // JSON усієї моделі
}

public function stats()
{
    return ['total' => Post::count()];  // JSON масиву
}

Чому цього замало. Модель віддає всі свої поля, тож у відповідь потрапляє те, чого там бути не повинно, а перейменування колонки мовчки змінює формат API для всіх клієнтів.

API Resource - це шар між моделлю та JSON, який описує форму відповіді явно:

php artisan make:resource PostResource
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'published_at' => $this->published_at?->toIso8601String(),
            'author' => new UserResource($this->whenLoaded('author')),
        ];
    }
}

Використання:

public function show(Post $post)
{
    return new PostResource($post);
}

public function index()
{
    return PostResource::collection(Post::paginate());
}

collection() разом із пагінацією сам додає блоки links і meta.

Що це дає: структура відповіді описана в одному місці, поля з бази не протікають назовні, дати мають єдиний формат, а whenLoaded() додає звʼязок лише тоді, коли його справді завантажили - і тим самим не створює N+1.

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

API Resource - шар трансформації між Eloquent-моделлю та JSON-відповіддю. Дає повний контроль над структурою API, відв'язуючи її від схеми БД.

class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'author' => UserResource::make($this->whenLoaded('author')),
            'createdAt' => $this->created_at->toIso8601String(),
        ];
    }
}

return PostResource::collection($posts);
  • whenLoaded() додає зв'язок лише якщо він eager-завантажений (без N+1).
  • Resource Collections дозволяють додавати метадані (meta, links).

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

Idempotency (ідемпотентність) - багаторазове виконання операції дає той самий результат, що й однократне. Критично для платежів і повторів завдань у чергах (де доставка «at least once»).

Реалізація для API - idempotency key:

$key = $request->header('Idempotency-Key');

return Cache::lock("idem:$key")->block(5, function () use ($key) {
    if ($cached = Cache::get("idem:result:$key")) {
        return $cached; // повернути попередній результат
    }
    $result = $this->charge(); // виконати один раз
    Cache::put("idem:result:$key", $result, now()->addDay());
    return $result;
});

Для завдань: перевірка «вже оброблено» за унікальним ключем, ShouldBeUnique, або БД-обмеження, що відсікають дублі.

Версіонування дозволяє розвивати API, не ламаючи наявних клієнтів. Стратегії:

URI versioning (найпоширеніше) - версія в шляху:

Route::prefix('v1')->group(base_path('routes/api_v1.php'));
Route::prefix('v2')->group(base_path('routes/api_v2.php'));

Header/Media-type versioning - Accept: application/vnd.app.v2+json. Чистіші URL, але складніше тестувати.

Практики:

  • Окремі неймспейси контролерів і API Resources на версію (V1\PostResource, V2\PostResource).
  • Бізнес-логіку виносити в спільні Action/Service, щоб не дублювати між версіями.
  • Політика deprecation: підтримувати стару версію певний строк, повертати заголовки Deprecation/Sunset.

Докладніше в документації: API Resources (версіонування)

  • Ресурсна модель URL: іменники в множині (/posts, /posts/{id}/comments), дія - через HTTP-метод, а не в URL.
  • Коректні статус-коди: 200/201/204, 422 (валідація), 401/403, 404, 429.
  • API Resources для відповіді - щоб відв'язати JSON від схеми БД і контролювати формат.
  • Версіонування (/v1) із самого старту.
  • Пагінація, фільтрація, сортування через query-параметри; не віддавати все одразу.
  • Consistent error format - єдина структура помилок (Laravel дає { "message": ..., "errors": {...} } для 422).
  • Автентифікація через Sanctum/Passport, rate limiting на маршрутах.
  • Idempotency для небезпечних повторюваних операцій (платежі).
  • Документація (OpenAPI/Scribe) і контрактні тести.

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