Подписывайтесь на наш Telegram канал и будьте в курсе всех событий.

Паттерн Конвейер (Pipeline Pattern) в Laravel

Пайплайны предоставляют элегантное решение для последовательного применения множества фильтров к запросу Eloquent. В Laravel пайплайны позволяют инкапсулировать логику фильтрации в отдельные классы и затем последовательно применять их к запросу. Это повышает читаемость, тестируемость и расширяемость кода.

Давайте рассмотрим, как можно использовать пайплайны для реализации фильтров в Eloquent:

Шаг 1: Создание фильтров

Каждый фильтр будет отдельным классом, реализующим интерфейс FilterInterface.

<?php

namespace App\Pipelines\Filters;

use Illuminate\Database\Eloquent\Builder;

interface FilterInterface
{
    public static function apply(Builder $builder, $value): Builder;
}

Примеры фильтров:

Фильтр по названию:

<?php

namespace App\Pipelines\Filters;

use Illuminate\Database\Eloquent\Builder;

class NameFilter implements FilterInterface
{
    public static function apply(Builder $builder, $value): Builder
    {
        return $builder->where('name', 'like', '%' . $value . '%');
    }
}

Фильтр по категории:

<?php

namespace App\Pipelines\Filters;

use Illuminate\Database\Eloquent\Builder;

class CategoryFilter implements FilterInterface
{
    public static function apply(Builder $builder, $value): Builder
    {
        return $builder->where('category', $value);
    }
}

Фильтр по цене:

<?php

namespace App\Pipelines\Filters;

use Illuminate\Database\Eloquent\Builder;

class PriceFilter implements FilterInterface
{
    public static function apply(Builder $builder, $value): Builder
    {
        return $builder->whereBetween('price', [$value['min'], $value['max']]);
    }
}

Шаг 2: Создание класса пайплайна

Создайте класс ProductPipeline, который будет последовательно применять фильтры.

<?php

namespace App\Pipelines;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Pipeline;

class ProductPipeline
{
    protected array $filters = [];

    public function __construct(array $filters)
    {
        $this->filters = $filters;
    }

    public function apply(Builder $builder): Builder
    {
        return app(Pipeline::class)
            ->send($builder)
            ->through($this->filters)
            ->thenReturn();
    }
}

Шаг 3: Применение пайплайнов в контроллере

Используйте пайплайн в контроллере для фильтрации данных.

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Pipelines\Filters\NameFilter;
use App\Pipelines\Filters\CategoryFilter;
use App\Pipelines\Filters\PriceFilter;
use App\Pipelines\ProductPipeline;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

/**
 * Class ProductController
 */
class ProductController extends Controller
{
    /**
     * Получение списка продуктов с фильтрацией
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function index(Request $request): JsonResponse
    {
        $pipeline = new ProductPipeline([
            NameFilter::class,
            CategoryFilter::class,
            PriceFilter::class,
        ]);

        $products = $pipeline->apply(Product::query())->get();

        return response()->json($products);
    }
}

Шаг 4: Валидация входящих данных

Создайте FormRequest для валидации входящих данных.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

/**
 * Class ProductFilterRequest
 */
class ProductFilterRequest extends FormRequest
{
    /**
     * Правила валидации
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'name'     => 'nullable|string|max:255',
            'category' => 'nullable|string|max:255',
            'price'    => 'nullable|array',
            'price.min'=> 'nullable|numeric|min:0',
            'price.max'=> 'nullable|numeric|min:0',
        ];
    }
}

Заключение

Использование пайплайнов для фильтрации данных в Eloquent позволяет легко и элегантно управлять сложными запросами. Это улучшает читаемость кода и упрощает его поддержку, предоставляя более гибкий и модульный способ обработки запросов.

Inn_100_gramm

Если вы видите это, значит, я еще не придумал, что написать.

0

Вакансии

Спонсоры

Помощь в разработке вашего проекта на Laravel

Независимо от сложности проекта эти кампании помогают сообществу и всем его участникам воплощать идеи в элегантные приложения.

Присоединиться

Инструменты для управления эмоциями, которые помогают людям контролировать свою жизнь и лучше понимать себя.

Перейти

Подкасты c зажигательными эпизодами, которые заставят задуматься и приведут к новым перспективам.

Перейти