Зупиніть лавини N+1: впровадьте Laravel Strict Mode

Проблема запитів N+1 вбиває продуктивність бази даних. Вона виникає, коли ви отримуєте список записів і перебираєте їх у циклі, щоб отримати доступ до зв'язку. Ви забули завантажити цей зв'язок заздалегідь.

Припустимо, ви відображаєте 50 інвойсів на панелі керування. Ви перебираєте їх у циклі, щоб показати ім'я клієнта. Ви забули використати метод with. Eloquent виконує 1 запит для інвойсів. Потім він виконує 50 окремих запитів для кожного клієнта.

Під час локальної розробки 51 запит займає 10 мілісекунд. Ви цього не помітите. У продакшені велике навантаження перетворює це на лавину. Це вичерпує пул з'єднань з базою даних і призводить до збою сервера.

Ви не можете покладатися лише на перегляд коду (code reviews). Вам потрібні архітектурні запобіжники.

Laravel пропонує Strict Mode для вирішення цієї проблеми. Ви можете використовувати preventLazyLoading на рівні додатка. Laravel відстежуватиме ваші зв'язки з базою даних. Якщо під час локальної розробки або тестування він виявить ліниве завантаження (lazy load), він викине виключення (exception). Це змусить вас негайно виправити код.

Як це налаштувати:

Налаштуйте механізм безпеки у вашому AppServiceProvider. Зробіть це для локального середовища та середовища тестування. У продакшені замість зупинки додатка варто лише логувати помилку.

Використовуйте ці три налаштування у вашому методі boot:

  • Model::preventLazyLoading: зупиняє запити N+1.
  • Model::preventSilentlyDiscardingAttributes: запобігає помилкам масового присвоєння (mass assignment).
  • Model::preventAccessingMissingAttributes: запобігає витокам пам'яті через відсутні зв'язки.

Для продакшену використовуйте handleLazyLoadingViolationUsing. Це дозволить вам логувати порушення у Slack або сервіс логування. Ви отримаєте можливість контролювати ситуацію, не порушуючи досвід користувачів.

Впровадження Strict Mode переносить оптимізацію на початок вашого робочого процесу (pipeline). Запити N+1 не зможуть пройти через ваші тести. Ваш кодовий бази залишатиметься оптимізованим, а база даних — швидкою.

Джерело: https://dev.to/iprajapatiparesh/stop-n1-avalanches-enforce-laravel-strict-mode-2oop