A PSR-15 server request handler.

Overview

Relay

A PSR-15 request handler.

This package is installable and PSR-4 autoloadable via Composer as "relay/relay": "~2.0".

Alternatively, download a release or clone this repository, then map the Relay\ namespace to the package src/ directory.

This package requires PHP 7.1 or later. You should use the latest available version of PHP as a matter of principle.

To run the tests, issue composer install to install the test dependencies, then issue ./vendor/bin/phpunit.

Please see http://relayphp.com/ for documentation.

Comments
  • How does Relay fit in with Radar and Spark?

    How does Relay fit in with Radar and Spark?

    UPDATE FOR LATER READERS: the Pipeline project was renamed to Relay shortly after announcement.

    Taking our conversation from email to Github so that others can have some input...

    On Jun 5, 2015, at 12:57, Woody Gilk [email protected] wrote:

    What's your vision for PipelinePHP? Do you want to roll Pipeline into Spark and share collaboration on it, or are you thinking that Pipeline should be the nexus between Spark and Radar?

    I see Pipeline as the nexus between the two, and (one hopes) a wide range of other middleware systems. The idea would be, again one hopes, for a collection of middleware packages to spring up that follow the same signature and expectations. Then Radar, and Spark, and whatever-else-comes can say they are Pipeline compliant.

    We're nearly ready to start prototyping with Spark and would like to get this sorted out soon so that we can collaborate more closely and work on core ADR stuff together, rather than duplicating efforts.

    /me nods

    As far as core ADR stuff, Pipeline might provide a good non-project-specific nexus, or maybe not. There's a case for publishing separate package that is not attached to any particular project.

    Regardless, the fact that the middleware dispatching is separated out means each project gets to its own .env setup (before Pipeline), container setup (which creates Pipeline and other objects), and middleware objects (which Pipeline executes). Those surrounding pieces are where the fun and preferences live.

    You've already talked about this, but I'll reiterate. I think the remaining pieces for an ADR set of interfaces are:

    • An Action handler signature. It strikes me that this ought to be "just another middleware." It takes $request, $response, $next, and returns a $response. As such, it might not need an interface per se, but it would need a set of expectations on how to pick the classes for the action. Information from the routing phase might be passed as ServerRequest attributes: e.g., ['adr:input' => 'InputClassName', 'adr:domain' => 'DomainClassName', 'adr:responder' => 'ResponderClassName']. Actions would expect those to be there, and to use them appropriately (whatever that means).
    • I don't know that a common Route interface would be needed, so long as the Action-related specifics of the route can be passed through to a later Action handler. Tough to type hint with a standard middleware signature in place. Alternatively, an ActionDescriptor might be good, and it would carry the input/domain/responder information, possibly along with the means to create those objects for the Action. It would still have to be passed via the $request as an attribute, maybe "adr:descriptor".
    • A common Input interface sounds good. __invoke(ServerRequest $request) would be just fine, which you have in place. The return would have to be an array of params suitable for call_user_func_array().
    • I don't know that a common Domain interface is really needed. call_user_func_array($domain, $input($request)) seems to cover every possible case.
    • A common Responder interface is a little tricky. Although I like the idea of __invoke($request, $response, $payload = null), I have to wonder about the Payload interface at that point. Do we require one, or do we just say "$payload is whatever comes back from your Domain"?

    Actual implementations of these, might go well in their own projects. That would mean an interface-only package, and then separate projects that implement them according to the desires of the implementors.

    (/me wipes brow)

    None of that is set in stone, obviously, but it seems like a good start combined with your spark/adr work.

    Over to you!

    opened by shadowhand 45
  • Please Review 2.x

    Please Review 2.x

    @mindplay-dk @elazar @renan @KorvinSzanto @shadowhand --

    As noted in #17, we needed to modify the middleware interface signature, but it was a BC break, thus making a major version bump necessary.

    The new BC-breaking middleware interface is now in the 2.x branch. I have added some other non-BC-breaking changes, such as the run() methods that Rasmus wanted, and a Last middleware class instead of an embedded closure. Please review and test the changes; now is your chance to speak your mind, or forever hold your peace!

    opened by pmjones 29
  • Changing Project Name

    Changing Project Name

    @andersonamuller @badlamer @bradleyboy @byoigres @calvinfroedge @clickalicious @coderabbi @coldwinds @cwscribner @davidpersson @dbonner1987 @dolfelt @elazar @FallingBullets @ferceg @garrettw @gsahr @hkulekci @hmert @hossein- @jakejohns @jensscherbl @jessupdw @johnutzm @jpcercal @khanhicetea @KingCrunch @koriym @lifesign @lku @markstory @mcrumm @Meroje @mikedfunk @mkraemer @nikolay @ojhaujjwal @pqr @ronanguilloux @shameerc @shyuan @silentworks @texdc @tuupola @websoftwares @wsuff @xduh @ytake @zanderbaldwin

    tl;dr: I'll be renaming "Pipeline" to "Relay" in the near future. Read on for details.


    Naming is one of the two hard things in programming.*

    A commenter on Reddit pointed out that Pipeline doesn't actually implement the "pipeline" design pattern. I did look up that pattern before settling on the name, but my cursory review was insufficient. It turns out that the libary implementation is not really close enough to the pattern to be called a pipeline proper. As such, there is reason to believe programmers familiar with the pattern will be confused and/or irritated by the name.

    To avoid diffusing the term "pipeline", and to honor my own desire for common vocabulary (cough Facade cough), I'll be renaming the project to "Relay." I have discovered no existing software design pattern of that name, and no other PHP project of that name. It does seem to convey the underlying operation of the libary (each request is relayed to the next middleware, and each response is relayed back in turn).

    The plan is to rename the Github organization from "pipelinephp" to "relayphp", the site from "pipelinephp.com" to "relayphp.com", the library from "Pipeline.Pipline" to "Relay.Relay", the underlying classes from Pipeline* to Relay*, and the composer pacakge from "pipeline/pipeline" to "relay/relay". All your existing Github forks and checkouts should continue to work, but you will need to update your composer.json files.

    I expect to accomplish this later today or early tomorrow. I will update this issue when it's done.

    My apologies for having done insuffient research in the first place, and for this ensuing hassle. Thank you for your patience with this early-stage project.

    (* The others are cache-clearing and off-by-one errors.)

    opened by pmjones 17
  • No access to real request object in middleware on the response's way out

    No access to real request object in middleware on the response's way out

    Since ->withAttribute and ->getAttribute only exist on \Psr\Http\Message\ServerRequestInterface which is immutable, important things that need to be passed through by a middleware might not be available on the way out. An example of this being an issue is maybe a cookie encrypting middleware:

    class CookieEncryptor
    {
    
        use CookieEncryptingTrait, CookieDecryptingTrait, CookieSerializingTrait;
    
        public function __invoke($request, $response)
        {
            // Before the router
            $cookies = $this->decryptedCookies($request);
            $request = $request->withAttribute('cookies', $cookies);
    
            $response = $next($request, $response);
            // After the router
            // $request and $cookies may have been replaced, but we have no way to know.
            return $response->withHeader('Set-cookie', $this->serializeCookies($this->encryptedCookies($cookies->getModified())));
        }
    
    }
    

    One way to fix this is to append a reversed version of the queue onto the queue before sending a request and response, but then the middleware has to maintain state and the recommended way of catching the response on the way out becomes confusing.

    Thoughts?

    opened by KorvinSzanto 15
  • Fix array detection bug in builder

    Fix array detection bug in builder

    The correct way to detect for objects that can be used as iterators is against the Traversable interface. This works for ArrayObject and any other objects that implement iterator interfaces.

    http://php.net/traversable

    Fixes #21

    opened by shadowhand 13
  • Allow to use the same instance multiple times

    Allow to use the same instance multiple times

    Currently, the __invoke() method of Relay use array_shift to get the next middleware from the queue. I think it should better to use next() to get the element without remove it, so the queue should be used multiple times:

    $dispatcher = new Relay([$middleware1, $middleware2]);
    
    $response = $dispatcher(new ServerRequest(), new Response());
    $response2 = $dispatcher(new ServerRequest(), new Response());
    
    opened by oscarotero 12
  • 2.x $next isn't callable

    2.x $next isn't callable

    Documentation suggests that $next is callable, but the $next is always a Runner instance, which doesn't implement __invoke

    function (
        Request $request, // the request
        callable $next // the next middleware or handler
    ) : Response {
        // ...
    }
    
    opened by urugator 9
  • Error Handler Support

    Error Handler Support

    Error handlers are middleware with an arity of four and can be invoked by adding a third argument to the $next call.

    Invoking an error:

    $next($request, $response, 'error occurred');
    

    Middleware signature:

    function($error, $request, $response, $next)
    

    What's nice about error handlers is that when an error is invokved (via an exception, or a call to next with three arguments) you can go through the error handler queue and have a logger, maybe an error page render, etc.

    Any plans on implementing something similar to Relay?

    opened by spiffyjr 8
  • PSR-15 RequestHandlerInterface items

    PSR-15 RequestHandlerInterface items

    My understanding - with PSR-15, you have MiddlewareInterface and RequestHandlerInterface - both of which essentially are means to the same end - getting a Response instance back. In Relay, if you don't "cap" the end, you'll get an error. So in the documentation, there's this:

    $queue[] = new FooMiddleware();
    $queue[] = new BarMiddleware();
    $queue[] = new BazMiddleware();
    // ...
    $queue[] = new ResponseFactoryMiddleware {
        return new Response();
    };
    

    My question - would it not be better to add support for RequestHandlerInterface items in the queue and not just MiddlewareInterface ones? So in Runner.php

    if ($middleware instanceof MiddlewareInterface) {
       return $middleware->process($request, $this);
    }
    
    // this is what i propose we add, too:
    if ($middleware instanceof RequestHandlerInterface) {
       return $middleware->handle($request);
    }
    

    This way, you can add a definitive end to your queue, or even pass off to an entirely different Relay queue thanks to Relay implementing RequestHandlerInterface...

    It's not a wild change and sure, I could typically wrap what I need in an open-ended Middleware. It feels though that adding the above would avoid such workarounds whilst supporting the rest of PSR-15 and allowing you to cap things off properly.

    opened by wirebox-platform 7
  • Feature request - possibly add support for 'trampolining'

    Feature request - possibly add support for 'trampolining'

    Hello :)

    One side-effect of middleware stacks seems to be very long exception stacks when something goes wrong. I heard a term 'trampolining' as a way to reduce this issue and thought it might be a good feature request. I think, basically, the technique unwinds the stack periodically. I guess this would mean a large change to the way middlewares are dispatched because you'd not be able to just call middleware A which then calls B which then calls C etc. Instead you'd have to use a loop or similar.

    Something to ponder, maybe?

    Robert

    opened by far-blue 7
  • Allow to use the dispatcher as a middleware

    Allow to use the dispatcher as a middleware

    (This comes from https://github.com/oscarotero/psr7-middlewares/issues/34)

    It should be great to have the posibility of using the dispatcher as a middleware of other dispatcher. Example:

    use Relay\Runner;
    
    $group = new Runner([
        new Middleware1(),
        new Middleware2(),
    ]);
    
    $dispatcher = new Runner([
        $group,
        new Middleware3()
    ]);
    
    opened by oscarotero 7
Releases(2.1.2)
  • 2.1.2(Jun 4, 2021)

    Lots of nice little dev-related changes:

    • Run PHPUnit v9.5, if possible
    • Add void returns to unit tests (#54 & #57)
    • Start testing against PHP 8.0 (#55)
    • Update Psalm to v4.7
    • Update PHP-CS-Fixer to v3.0
    • Update Doctrine Coding Standard to v9 (#57)
    • Switch from TravisCI to GitHub Actions since travis-ci.org is shutting down (#56)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.1(Mar 18, 2020)

    • Fix a bug where Traversable queues (non-array iterables) will fail because the reset(), current(), and next() array functions are incompatible
    • Improve the overall code quality of the project (through internal changes that do not alter the public API)
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Mar 4, 2020)

    • Raise a more obvious error message when Relay is given an empty queue (#43)
    • Fix a bug that broke callable middleware (#45)
    • Properly declare PSR dependencies and make it clear that Relay provides an implementation of PSR-15's Psr\Http\Server\RequestHandlerInterface (#46)
    • Add support for queue items that implement Psr\Http\Server\RequestHandlerInterface (#48)
    • Replace abandoned zendframework/zend-diactoros with same version laminas/laminas-diactoros
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Mar 31, 2019)

    The 2.x series introduces a major change to the way Relay handles middleware. While the 1.x series featured a "double pass" signature (function (request, response, next)), the 2.x series is fully-compatible with PSR-15's "single pass" or "lambda" recommendation (function (request, handler) : response).

    Note that middleware designed for Relay 1.x are not compatible with PSR-15 server request handlers ("dispatchers") like Relay 2.x.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-rc.1(Mar 24, 2019)

  • 2.0.0-alpha1(Feb 13, 2018)

    CHANGELOG

    This is the changelog for the 2.x series.

    2.0.0-alpha1

    The 2.x series converts from a function (request, response, next) ("double pass") signature to a function (request, handler) : response ("single pass" or "lambda") signature.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Dec 17, 2015)

  • 1.0.0(Oct 14, 2015)

  • 0.2.0(Jun 25, 2015)

    Making this release specifically users you can lock to it before the upcoming BC-breaking changes currently in the "new-reusable" branch.

    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jun 21, 2015)

PSR-15 middleware in minutes!

zend-expressive Repository abandoned 2019-12-31 This repository has moved to mezzio/mezzio. Develop PSR-7 middleware applications in minutes! zend-exp

Zend Framework 718 Dec 9, 2022
[DEPRECATED] Collection of PSR-7 middlewares

This package is deprecated in favor of the new PSR-15 standard. Check it out here psr7-middlewares Collection of PSR-7 middlewares. Requirements PHP >

Oscar Otero 669 Dec 27, 2022
PSR-15 middleware for Symfony framework.

PSR-15 middleware now in Symfony Contents Installation Configuration Usage Examples Customization Caching Real World Example Middlewares Testing Licen

kafkiansky 60 Dec 14, 2022
A super simple, clean and pretty error handler that replace the default error handler of PHP. You need only include this file!

php-custom-error-handler A super simple, clean and pretty error handler that replace the default error handler of PHP. You need just include only this

null 6 Nov 7, 2022
A simple and flexible PHP middleware dispatcher based on PSR-7, PSR-11, and PSR-15

Woohoo Labs. Harmony Woohoo Labs. Harmony is a PSR-15 compatible middleware dispatcher. Harmony was born to be a totally flexible and almost invisible

Woohoo Labs. 153 Sep 5, 2022
A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

Minibase 16 Jun 7, 2022
A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

Minibase 16 Jun 7, 2022
Error handler with PSR-7 support

Jasny Error Handler Error handler with PSR-7 support. Installation The Jasny Error Handler package is available on packagist. Install it using compose

Arnold Daniels 6 Jun 23, 2022
PSR-15 middleware to use Whoops as error handler

middlewares/whoops Middleware to use Whoops as error handler. Requirements PHP >= 7.2 A PSR-7 http library A PSR-15 middleware dispatcher Installation

Middlewares 31 Jun 23, 2022
PSR-15 compatible middleware for Whoops, the pretty error handler

PSR-15 middleware for Whoops A PSR-15 compatible middleware for Whoops, the fantastic pretty error handler for PHP. Installation You can install the l

Franz Liedke 25 May 20, 2022
This Package helps you in laravel application to log all desired activity for each request from request entry point to generate response at a single snapshot.

Laravel Scenario Logger This Package helps you in laravel application to log all desired activity for each request from request entry point to generat

Mehrdad Mahdian 6 Sep 27, 2021
Csrf Component provides Cross Site Request Forgery protection by comparing provided token with session token to ensure request validity.

Csrf Component Csrf Component provides Cross Site Request Forgery protection by comparing provided token with session token to ensure request validity

ATOMASTIC 3 Mar 12, 2022
HTTP Requestor: Package for a client request that supports you to make an external service request easily and with fast usage.

HttpRequestor from Patienceman HTTP Requestor: Package for a client request that supports you to make an external service request easily and with fast

Manirabona Patience 2 Aug 26, 2022
It validates PSR-7 messages (HTTP request/response) against OpenAPI specifications

NOTICE - THE PACKAGE HAS BEEN CONTRIBUTED TO THE PHP LEAGUE Go to https://github.com/thephpleague/openapi-psr7-validator This package is here for exis

Dmitry Lezhnev 167 Sep 29, 2022
It validates PSR-7 messages (HTTP request/response) against OpenAPI specifications

OpenAPI PSR-7 Message (HTTP Request/Response) Validator This package can validate PSR-7 messages against OpenAPI (3.0.x) specifications expressed in Y

The League of Extraordinary Packages 421 Jan 3, 2023
Server-side handler of DataTables Jquery Plugin for Laravel 4

Project is not being maintained actively. You will most likely find a better more actively maintained fork here https://github.com/yajra/laravel-datat

Bilal Gultekin 264 Jul 2, 2022
Middleware for PHP built on top of PSR-7 and PSR-15

zend-stratigility Repository abandoned 2019-12-31 This repository has moved to laminas/laminas-stratigility. From "Strata", Latin for "layer", and "ag

Zend Framework 236 Sep 9, 2022
Fast PSR-7 based routing and dispatch component including PSR-15 middleware, built on top of FastRoute.

Route This package is compliant with PSR-1, PSR-2, PSR-4, PSR-7, PSR-11 and PSR-15. If you notice compliance oversights, please send a patch via pull

The League of Extraordinary Packages 608 Dec 30, 2022
:tada: Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)

HTTP router for PHP 7.1+ (incl. PHP 8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger) Installation compo

Sunrise // PHP 151 Jan 5, 2023
PSR-6 cache implementation adapting a given PSR-16 instance

PSR-6 cache implementation adapting PSR-16 This package provides a PSR-6 cache instance when you only have a PSR-16 cache at hand. As PSR-6 is more fe

null 1 Oct 15, 2021