OpenAPI - машиночитаний опис API: маршрути, методи, параметри, тіла запитів, відповіді й коди помилок. Якщо специфікація є, типи на клієнті можна генерувати, а не писати вручну.
openapi-typescript перетворює специфікацію на TypeScript-типи:
npx openapi-typescript ./storage/api-docs/openapi.json -o ./resources/js/api/schema.d.ts
openapi-fetch - тонкий клієнт поверх fetch, типізований згенерованою схемою:
import createClient from 'openapi-fetch';
import type { paths } from './schema';
const api = createClient<paths>({ baseUrl: '/api' });
const { data, error } = await api.GET('/vacancies/{id}', {
params: { path: { id: 42 } },
});
if (error) {
// тип error - з описаних у специфікації відповідей з помилками
} else {
data.title; // тип відповіді 200
}
- шлях перевіряється: неіснуючий маршрут - помилка компіляції;
- параметри шляху, запиту й тіло - типізовані й обов'язкові, де вимагає специфікація;
- відповідь - різні типи для успіху й помилок.
Звідки специфікація в Laravel: пакети, що генерують OpenAPI з коду (наприклад, Scramble - аналізує маршрути, Form Request і ресурси), або написана вручну специфікація як контракт (підхід «спершу специфікація»).
Що це дає:
- один контракт для бекенду, фронтенду, мобільних клієнтів і документації;
- зміни API видно в diff згенерованих типів - і компілятор показує місця, що зламалися;
- документація (Swagger UI, Scalar) з того самого джерела.
Обмеження й пастки:
- типи не перевіряють дані під час виконання. Згенерований тип каже, що поле є, але якщо реалізація розійшлася зі специфікацією - помилка під час виконання. Для критичних даних додають перевірку (є генератори Zod-схем з OpenAPI);
- якість специфікації = якість типів. Автогенерація з коду може пропускати nullable-поля чи неочевидні формати - їх уточнюють анотаціями;
- регенерація в CI: перевіряти, що згенеровані файли відповідають поточній специфікації, інакше вони непомітно застаріють;
- версіонування API: зміни, що ламають сумісність, у специфікації мають бути явними - генерація типів робить їх видимими, але не вирішує проблему клієнтів, які ще не оновилися.
Коли варто: публічне чи велике внутрішнє API, кілька клієнтів, окремі команди бекенду й фронтенду. Для невеликого монолітного Laravel + Inertia - часто досить генерації типів з DTO і Wayfinder.