# Class HttpSoft\Runner\MiddlewarePipeline

Class, that implements HttpSoft\Runner\MiddlewarePipelineInterface and is responsible for building PSR-15 middleware pipelines.

Source code on GitHub.

use HttpSoft\Runner\MiddlewarePipeline;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 * @var Psr\Http\Server\MiddlewareInterface $siteMiddleware
 * @var Psr\Http\Server\MiddlewareInterface $userMiddleware
 */

$pipeline = new MiddlewarePipeline();

// Basic usage

$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');

$response = $pipeline->handle($request);
// Or
$response = $pipeline->process($request, $handler);

// Add custom middleware

$handlerMiddleware = new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
};

$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$pipeline->pipe($handlerMiddleware);

$response = $pipeline->handle($request);

# Public methods

See the original detailed description of the methods in the implemented interfaces:

# pipe

Adds an instance of Psr\Http\Server\MiddlewareInterface to the pipeline.

public function pipe(MiddlewareInterface $middleware, string $pathPrefix = null): void;

By specifying the path prefix, the middleware is attached to the specific path and will only be processed if the request URI path starts with the given prefix.

// Available: `https://example.com` and `https://example.com/any`:
$pipeline->pipe($commonMiddleware);
// Or
$pipeline->pipe($commonMiddleware, '');
// Or
$pipeline->pipe($commonMiddleware, '/');

// Available: `https://example.com/api` and `https://example.com/api/any`:
$pipeline->pipe($apiMiddleware, '/api');

// Available: `https://example.com/api/admin` and `https://example.com/api/admin/any`:
$pipeline->pipe($apiAdminMiddleware, '/api/admin');
// but not available: `https://example.com/api` and `https://example.com/api/any`.

The path prefix MUST start at the root, and the leading and trailing slashes are optional (/path or path or path/).

// One middleware can be attached to different paths:
$pipeline->pipe($authMiddleware, 'blog');
$pipeline->pipe($authMiddleware, '/forum');

// Multiple intermediate programs can be connected to the same path:
$pipeline->pipe($authMiddleware, 'admin/');
$pipeline->pipe($adminMiddleware, '/admin/');

This method is defined in HttpSoft\Runner\MiddlewarePipelineInterface.

# process

Runs all the middleware that was previously added to the pipeline in turn.

public function process(
    ServerRequestInterface $request, 
    RequestHandlerInterface $handler
): ResponseInterface;

If a middleware has not been previously added to the pipeline, which intercepts the handler and returns a response, the response generated by $handler will always be returned.

$pipeline = new MiddlewarePipeline();

// Returns a `Psr\Http\Message\ResponseInterface` instance from `$handler`:
$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$response = $pipeline->process($request, $handler);

// Returns a `Psr\Http\Message\ResponseInterface` instance from middleware:
$pipeline->pipe(new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
});
$response = $pipeline->process($request, $handler);

This method is defined in Psr\Http\Server\MiddlewareInterface.

# handle

Runs all the middleware that was previously added to the pipeline in turn.

public function handle(ServerRequestInterface $request): ResponseInterface;

Internally, it calls the process() method, into which the handler that throws the HttpSoft\Runner\Exception\EmptyMiddlewarePipelineException exception is passed. If a middleware has not been previously added to the pipeline, which intercepts the handler and returns a response, the exception will always be thrown.

$pipeline = new MiddlewarePipeline();

// Throws `HttpSoft\Runner\Exception\EmptyMiddlewarePipelineException`:
$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$response = $pipeline->handle($request);

// Returns a `Psr\Http\Message\ResponseInterface` instance:
$pipeline->pipe(new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
});
$response = $pipeline->handle($request);

This method is defined in Psr\Http\Server\RequestHandlerInterface.