Laravel Pipeline Pattern: Viết code sạch cho quy trình xử lý phức tạp
Refactor 'God Controller' thành chuỗi xử lý Pipeline thanh lịch. Cách áp dụng Design Pattern này để code Laravel dễ đọc và dễ test hơn.
Bạn có một Controller xử lý “Place Order” dài 500 dòng?
- Check tồn kho
- Validate coupon
- Tính thuế
- Charge thẻ tín dụng
- Gửi email confirm
- Notify Slack team
Nếu viết hết vào một function method: ác mộng để test và maintain.
Laravel cung cấp một công cụ ẩn rất mạnh: Illuminate\Pipeline\Pipeline.
Đây chính là cơ chế vận hành Middleware của Laravel, nhưng bạn có thể dùng nó cho Business Logic của mình.
Cách Implement
Đầu tiên, hãy định nghĩa các “Pipe” (các bước xử lý). Mỗi Pipe là một class.
// app/Pipes/CheckInventory.php
class CheckInventory
{
public function handle($order, Closure $next)
{
if (!Inventory::check($order->items)) {
throw new Exception("Out of stock");
}
return $next($order);
}
}
// app/Pipes/ApplyDiscount.php
class ApplyDiscount
{
public function handle($order, Closure $next)
{
if ($order->coupon) {
$order->total -= Coupon::calculate($order->coupon);
}
return $next($order);
}
}
Sau đó, sử dụng Pipeline trong Controller hoặc Service:
use Illuminate\Pipeline\Pipeline;
public function store(Request $request)
{
$order = new Order($request->all());
$processedOrder = app(Pipeline::class)
->send($order)
->through([
\App\Pipes\CheckInventory::class,
\App\Pipes\ApplyDiscount::class,
\App\Pipes\CalculateTax::class,
\App\Pipes\ProcessPayment::class,
])
->then(function ($order) {
$order->save();
return $order;
});
return response()->json($processedOrder);
}
Tại sao nó tuyệt vời?
- Single Responsibility: Mỗi class chỉ làm một việc duy nhất (Check kho riêng, Tính tiền riêng).
- Testability: Bạn có thể viết Unit Test cho từng Pipe cực dễ, không cần mock cả thế giới.
- Flexibility: Muốn tạm tắt chức năng Discount? Comment dòng
ApplyDiscount::class. Muốn thêm bước Log? ThêmLogStep::class. Không cần sửa logic chính.
Khi nào dùng?
- Quy trình Checkout / Payment.
- Xử lý file upload (Resize -> Watermark -> Upload S3 -> Save DB).
- Quy trình duyệt bài (Validate -> Check Offensive Words -> Notify Admin).
Đừng lạm dụng cho CRUD đơn giản. Nhưng với complex flows, Pipeline là cứu cánh cho Clean Code.
Mục đích chính của Pipeline Pattern trong Laravel là gì?
Thử Thách Kiến Thức Lịch Sử?
Khám phá hàng trăm câu hỏi trắc nghiệm lịch sử thú vị tại HistoQuiz. Vừa học vừa chơi, nâng cao kiến thức ngay hôm nay!