Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 4, 2021 12:41 pm GMT

Laravel Pipeline Design Pattern Example

Using laravel pipelines you can pass an object between several classes in a fluid way to perform any type of task and finally return the resulting value once all the tasks have been executed.

Larval uses the Pipeline Design Pattern in a couple of places throughout the framework. This means everything we need to implement this pattern is already part of the foundation of your application!

In todays tutorial we will be looking at the Pipeline Design Pattern and how we can filter data using laravel pipeline, in this tutorial we are going to see that.

laravel-pipeline-example

What is the Pipeline Design Pattern?
The Pipeline Design Pattern is where a complex process is broken down into individual tasks. Each individual task is reusable and so the tasks can be composed into complex processes.

This allows you to break up monolithic processes into smaller tasks that process data and then pass that data to the next step.

Each task within the pipeline should receive and emit the same type of data. This allows tasks to be added, removed, or replaced from the pipeline without disturbing the other tasks.

Now let's start our tutorial. In this tutorial we will create a post table, and filter them using active or inactive, asc or desc or will filter them order by title or name. That mean we are going to filter data using Laravel pipeline. Let's see.

Step 1 : Create Route

Now we have to create a route to return our data, so create it.

Route::get('post', [FilterController::class, 'index']);

Step 2 : Create Post Model

To create Post model, paste this code.

php artisan make:model Post -m

Now open our newly created database table and paste the following code.

<?phpuse Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema;class CreatePostsTable extends Migration{    public function up()    {        Schema::create('posts', function (Blueprint $table) {            $table->id();            $table->string('title');            $table->boolean('active')->comment('active or inactive');            $table->timestamps();        });    }    public function down()    {        Schema::dropIfExists('posts');    }}

Step 3: Generate some dummy data

To generate some dummy data, open PostFactory and paste below code

<?phpnamespace Database\Factories;use App\Models\Post;use Carbon\Carbon;use Illuminate\Database\Eloquent\Factories\Factory;class PostFactory extends Factory{    protected $model = Post::class;    public function definition()    {        return [            'title' => $this->faker->sentence,            'active' => $this->faker->boolean        ];    }}

and then run below command to generate fake data using faker.

php artisan tinker\App\Models\Post::factory(5)->create();exit

Step 4: Add Controller Method

Now at last we have to add new controller method index() in your Home Controller. So let's add index() method on HomeController.php file.

app/Http/Controllers/FilterController.php

<?phpnamespace App\Http\Controllers;use App\Models\Post;class FilterController extends Controller{    public function index()    {        $posts = Post::filtered()->paginate(2);        return view('post',compact('posts'));    }}

Step 5: Setup Model

Now open Post model, and paste this following code.

<?phpnamespace App\Models;use Illuminate\Pipeline\Pipeline;use Illuminate\Database\Eloquent\Model;class Post extends Model{    public static function filtered()    {       return app(Pipeline::class)                ->send(self::query())                ->through([                    \App\QueryFilters\Active::class,                    \App\QueryFilters\Sort::class,                    \App\QueryFilters\MaxCount::class,                ])                ->thenReturn();    }}

If you see the pipeline class source code which i mentioned link above, you will understand clearly what is happening here. Pipeline class define some classes like, you pass in the object that you want to send through the pipeline:

$pipeline->send($request); 

Next you pass an array of tasks that should accept and process the request:

$pipeline->through($middleware);  

Finally you run the pipeline with a destination callback:

$pipeline->then(function ($request) {  // Do something  });  

it also uses this below method which i used my code above.

    /**     * Run the pipeline and return the result.     *     * @return mixed     */    public function thenReturn()    {       //    }

Now we have to create our own custom class to filter our database data.

app/QueryFilters/Filter.php

<?phpnamespace App\QueryFilters;use Closure;use Illuminate\Support\Str;abstract class Filter {    public function handle($request, Closure $next)    {          if( ! request()->has($this->filterName())){            return $next($request);        }        $builder = $next($request);        return $this->applyFilters($builder);    }    abstract protected function applyFilters($builder);    protected function filterName()    {       return Str::snake(class_basename($this));    }}

app/QueryFilters/Active.php

<?phpnamespace App\QueryFilters;class Active extends Filter{    protected function applyFilters($builder)    {        return $builder->where('active',request($this->filterName()));    }}

app/QueryFilters/Sort.php

<?phpnamespace App\QueryFilters;class Sort extends Filter{    protected function applyFilters($builder)    {       return $builder->orderBy('title',request($this->filterName()));    }}

app/QueryFilters/MaxCount.php

<?phpnamespace App\QueryFilters;class MaxCount extends Filter{    protected function applyFilters($builder)    {       return $builder->take(request($this->filterName()));    }}

Now if you visit this url, you will find our filter data

http://127.0.0.1:8000/post?active=1&sort=desc&max_count=1

Now you should the below output. Here we can see our all active post with descending order. make sure that paginate and max_count can not work together.

If you get data from model without out using paginate method then max_count also work for filtering. See below code to understand. Hope you will understand.

$posts = app(Pipeline::class)                ->send(\App\Post::query())                ->through([                    \App\QueryFilters\Active::class,                    \App\QueryFilters\Sort::class,                    \App\QueryFilters\MaxCount::class,                ])                ->thenReturn()                ->paginate(2); //just change here like below code$posts = app(Pipeline::class)                ->send(\App\Post::query())                ->through([                    \App\QueryFilters\Active::class,                    \App\QueryFilters\Sort::class,                    \App\QueryFilters\MaxCount::class,                ])                ->thenReturn()                ->get();

1

http://127.0.0.1:8000/post?active=0&sort=desc&max_count=1

2

Now you should the below output. Here we can see our all inactive post with descending order.

Step 6 : Create View File

Now paste this following code to this post.blade.php file.

resources/views/post.blade.php

    <div class="card-body">       @foreach ($posts as $item)           {{ $item->title }}            {{ $item->active }} <br>       @endforeach    </div> {!! $posts->appends(request()->input())->links()  !!}

Laravel makes good use of this design pattern internally in the framework. But you can use Laravels Pipeline functionality for your own projects.

In next weeks tutorial were going to be looking at how you can use the Pipeline functionality to deal with complex processes. Hope it can help you to gather new knowledge.


Original Link: https://dev.to/abdallhsamy/laravel-pipeline-design-pattern-example-1pc9

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To