Коли контракт API погоджено (специфікація OpenAPI), фронтенд не повинен чекати на готовий бекенд. Мок-сервер відповідає за специфікацією.
Prism - мок-сервер, що читає OpenAPI:
npx @stoplight/prism-cli mock openapi.yaml
# слухає на http://127.0.0.1:4010
- статичні відповіді з полів
example/examplesспецифікації; - динамічні (
--dynamic) - згенеровані дані, що відповідають схемам; - валідація запитів: запит з неправильним тілом чи без обов'язкового параметра отримає 422 - фронтенд одразу бачить, що надсилає не те;
- вибір сценарію заголовком
Prefer: code=404чиPrefer: example=empty- перевірка обробки помилок; - режим проксі - перевіряє, що справжній сервер відповідає специфікації (контрольна точка між бекендом і контрактом).
MSW (Mock Service Worker) - моки на рівні клієнта:
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/vacancies/:id', ({ params }) =>
HttpResponse.json({ data: { id: Number(params.id), title: 'Laravel Developer' } }),
),
http.post('/api/applications', () =>
HttpResponse.json({ errors: { email: ['Обов\'язкове поле'] } }, { status: 422 }),
),
];
Service Worker у браузері (чи перехоплювач у Node для тестів) відповідає на запити застосунку. Код застосунку не знає про моки - робить звичайні fetch.
Порівняння:
- Prism - окремий сервер, що бере дані зі специфікації: моки не розходяться з контрактом;
- MSW - моки в коді, повний контроль над сценаріями (затримки, помилки мережі, стан між запитами), спільні для розробки, тестів і Storybook. Але їх треба підтримувати вручну або генерувати зі специфікації.
Головний ризик моків - розходження з реальністю. Фронтенд «працює» з моками, а з реальним API - ні. Захист:
- генерувати моки й типи з тієї самої специфікації, що й документацію;
- контрактні тести на бекенді (відповіді відповідають специфікації);
- регулярна перевірка на реальному тестовому оточенні до релізу.
Для бекенду на Laravel аналогічна задача - Http::fake() для сторонніх API в тестах.