A reusable and extensible pipeline package for Laravel applications.
This package provides a base pipeline class to process data through a series of customizable steps (pipes).
It adheres to Laravel's Illuminate\Pipeline
component, making it ideal for workflows that require sequential
processing.
- BasePipeline: Abstract class to define structured pipelines.
- Reusable Pipes: Create reusable steps for common processing logic.
- Extensible: Customize pipelines for various workflows.
- Tested: Fully unit-tested with 100% code coverage.
Install the package via Composer:
composer require your-vendor/pipeline
Extend the BasePipeline
class to create your pipeline:
use Skillcraft\PsychicFishstick\Abstracts\BasePipeline;
class ExamplePipeline extends BasePipeline
{
protected mixed $data;
public function __construct(mixed $data)
{
$this->data = $data;
}
protected function getInitialData(): mixed
{
return $this->data;
}
protected function pipes(): array
{
return [
\App\Pipes\StepOne::class,
\App\Pipes\StepTwo::class,
];
}
}
The GenericPipeline class is a flexible option for creating pipelines without defining a dedicated class. It is ideal for simple workflows.
use Skillcraft\PsychicFishstick\Pipelines\GenericPipeline;
// Mock data
$data = ['name' => 'Jane Doe'];
// Define pipes
$pipes = [
\App\Pipes\StepOne::class,
\App\Pipes\StepTwo::class,
];
// Instantiate and execute the pipeline
$pipeline = new GenericPipeline($data, $pipes);
$result = $pipeline->execute();
print_r($result);
/*
Output:
[
'name' => 'Jane Doe',
'step_one' => 'Processed by StepOne',
'step_two' => 'Processed by StepTwo',
]
*/
Use Case | GenericPipeline |
BasePipeline |
---|---|---|
Simple workflows | Ideal for one-off or straightforward cases. | Overhead of defining a class is unnecessary. |
Reusable workflows | Can work but lacks structured organization. | Better suited for well-defined pipelines. |
Extensibility | Less extensible without adding complexity. | Encourages a structured, extensible design. |
Type safety | Not enforced for pipes or data. | Ensures strict contracts and uniformity. |
A pipe is a step in the pipeline. Each pipe processes the data and passes it to the next step.
namespace App\Pipes;
use Closure;
class StepOne
{
public function handle($data, Closure $next)
{
$data['step_one'] = 'Processed by StepOne';
return $next($data);
}
}
Another example:
namespace App\Pipes;
use Closure;
class StepTwo
{
public function handle($data, Closure $next)
{
$data['step_two'] = 'Processed by StepTwo';
return $next($data);
}
}
Use your pipeline to process data:
$data = ['name' => 'John Doe'];
$pipeline = new ExamplePipeline($data);
$result = $pipeline->execute();
print_r($result);
/*
Output:
[
'name' => 'John Doe',
'step_one' => 'Processed by StepOne',
'step_two' => 'Processed by StepTwo',
]
*/
A reusable pipe for logging messages.
namespace Skillcraft\PsychicFishstick\Pipes;
use Closure;
use Illuminate\Support\Facades\Log;
class LoggingPipe
{
protected string $message;
public function __construct(string $message)
{
$this->message = $message;
}
public function handle($data, Closure $next)
{
Log::info($this->message, ['data' => $data]);
return $next($data);
}
}
use Skillcraft\PsychicFishstick\Abstracts\BasePipeline;
use Skillcraft\PsychicFishstick\Pipes\LoggingPipe;
class YourLoggingPipeline extends BasePipeline
{
protected mixed $data;
public function __construct(mixed $data)
{
$this->data = $data;
}
protected function getInitialData(): mixed
{
return $this->data;
}
protected function pipes(): array
{
return [
new LoggingPipe('Processing data in the pipeline'),
];
}
}
$data = ['key' => 'value'];
$pipeline = new LoggingPipeline($data);
$result = $pipeline->execute();
A reusable pipe for dispatching events.
namespace Skillcraft\PsychicFishstick\Pipes;
use Closure;
class EventTriggerPipe
{
protected string $eventClass;
protected array $eventData;
public function __construct(string $eventClass, array $eventData = [])
{
$this->eventClass = $eventClass;
$this->eventData = $eventData;
}
public function handle($data, Closure $next)
{
event(new $this->eventClass($data, ...$this->eventData));
return $next($data);
}
}
use Skillcraft\PsychicFishstick\Abstracts\BasePipeline;
use Skillcraft\PsychicFishstick\Pipes\EventTriggerPipe;
class EventPipeline extends BasePipeline
{
protected mixed $data;
public function __construct(mixed $data)
{
$this->data = $data;
}
protected function getInitialData(): mixed
{
return $this->data;
}
protected function pipes(): array
{
return [
new EventTriggerPipe(\App\Events\DataProcessed::class, ['extra' => 'value']),
];
}
}
$data = ['key' => 'value'];
$pipeline = new EventPipeline($data);
$result = $pipeline->execute();
This package includes DDEV for local environment management, ensuring an easy-to-use, consistent development environment.
- Install DDEV.
-
Clone the repository:
git clone https://github.com/skillcraft-io/psychic-fishstick.git cd psychic-fishstick
-
Start the DDEV environment:
ddev start
-
Install dependencies using Composer:
ddev composer install
-
Run tests to verify the setup:
ddev exec ./vendor/bin/pest
-
Access your project:
- Web: Nothing (This is just a package and has no views or even routes).
- CLI: Use
ddev exec
for running commands in the container.
./vendor/bin/pest
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bugfix.
- Write tests for your changes.
- Submit a pull request.
This package is open-sourced software licensed under the MIT license.