thephpleague/pipeline

Name: pipeline

Owner: The League of Extraordinary Packages

Description: League\Pipeline

Created: 2015-06-21 15:09:38.0

Updated: 2018-05-23 01:30:02.0

Pushed: 2018-01-10 07:36:53.0

Homepage: http://pipeline.thephpleague.com

Size: 50

Language: PHP

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

League\Pipeline

Author Build Status Coverage Status Quality Score Software License Packagist Version Total Downloads SensioLabsInsight

This package provides a pipeline pattern implementation.

Pipeline Pattern

The pipeline pattern allows you to easily compose sequential stages by chaining stages.

In this particular implementation the interface consists of two parts:

A pipeline consists of zero, one, or multiple stages. A pipeline can process a payload. During the processing the payload will be passed to the first stage. From that moment on the resulting value is passed on from stage to stage.

In the simplest form, the execution chain can be represented as a foreach:

ult = $payload;

ach ($stages as $stage) {
$result = $stage($result);


rn $result;

Effectively this is the same as:

ult = $stage3($stage2($stage1($payload)));
Immutability

Pipelines are implemented as immutable stage chains. When you pipe a new stage, a new pipeline will be created with the added stage. This makes pipelines easy to reuse, and minimizes side-effects.

Usage

Operations in a pipeline, stages, can be anything that satisfies the callable type-hint. So closures and anything that's invokable is good.

eline = (new Pipeline)->pipe(function ($payload) {
return $payload * 10;

Class based stages.

Class based stages are also possible. The StageInterface can be implemented which ensures you have the correct method signature for the __invoke method.

League\Pipeline\Pipeline;
League\Pipeline\StageInterface;

s TimesTwoStage implements StageInterface

public function __invoke($payload)
{
    return $payload * 2;
}


s AddOneStage implements StageInterface

public function __invoke($payload)
{
    return $payload + 1;
}


eline = (new Pipeline)
->pipe(new TimesTwoStage)
->pipe(new AddOneStage);

eturns 21
eline->process(10);
Re-usable Pipelines

Because the PipelineInterface is an extension of the StageInterface pipelines can be re-used as stages. This creates a highly composable model to create complex execution patterns while keeping the cognitive load low.

For example, if we'd want to compose a pipeline to process API calls, we'd create something along these lines:

cessApiRequest = (new Pipeline)
->pipe(new ExecuteHttpRequest) // 2
->pipe(new ParseJsonResponse); // 3

eline = (new Pipeline)
->pipe(new ConvertToPsr7Request) // 1
->pipe($processApiRequest) // (2,3)
->pipe(new ConvertToResponseDto); // 4 

eline->process(new DeleteBlogPost($postId));
Pipeline Builders

Because pipelines themselves are immutable, pipeline builders are introduced to facilitate distributed composition of a pipeline.

The pipeline builders collect stages and allow you to create a pipeline at any given time.

League\Pipeline\PipelineBuilder;

repare the builder
elineBuilder = (new PipelineBuilder)
->add(new LogicalStage)
->add(new AnotherStage)
->add(new LastStage);

uild the pipeline
eline = $pipelineBuilder->build();
Exception handling

This package is completely transparent when dealing with exceptions. In no case will this package catch an exception or silence an error. Exceptions should be dealt with on a per-case basis. Either inside a stage or at the time the pipeline processes a payload.

eline = (new Pipeline)->pipe(function () {
throw new LogicException();


{
$pipeline->process($payload);
tch(LogicException $e) {
// Handle the exception.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.