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

Як використовувати Pipeline для багатокрокових процесів у Laravel?

Illuminate\Pipeline - механізм, на якому побудовані middleware: об'єкт проходить послідовністю «труб», кожна може змінити його, передати далі чи зупинити процес.

use Illuminate\Support\Facades\Pipeline;

$order = Pipeline::send($order)
    ->through([
        EnsureItemsAvailable::class,
        ApplyPromoCode::class,
        CalculateShipping::class,
        CalculateTaxes::class,
    ])
    ->thenReturn();
final class ApplyPromoCode
{
    public function __construct(private PromoCodes $promoCodes) {}

    public function handle(Order $order, Closure $next): Order
    {
        if ($order->promo_code) {
            $order->discount = $this->promoCodes->discountFor($order);
        }

        return $next($order);
    }
}

Кроки створюються контейнером - залежності впроваджуються автоматично. Крок може бути класом, замиканням чи рядком Class:параметр.

Де пайплайн доречний:

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

Переваги:

  • кожен крок - маленький клас з однією відповідальністю, тестується окремо;
  • порядок і склад кроків видно в одному місці;
  • новий крок не змінює наявні.

Корисні можливості:

  • ->via('process') - інша назва методу кроків замість handle;
  • ->then(fn ($order) => ...) - фінальна дія після всіх кроків;
  • транзакція навколо всього пайплайну - Pipeline::send(...)->withinTransaction() (у нових версіях Laravel) або DB::transaction навколо виклику;
  • умовні кроки - збирати масив кроків за умовами перед through().

Пастки:

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

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

Схожі питання