If I am following you, your issue is more that you would want to see three different types of middleware: Passthrough a request (with modification), turn request to response, and passthrough response (with modification). Is that more accurate? The core of a middleware dispacher would then be:

foreach ($requestHandlers as $h) {
  $req = $h->process($req);
}
$res = $coreHandler->process($req);
foreach ($responseHandlers as $h) {
  $res = $h->process($res);
}

Is that more what you're talking about?

--Larry Garfield

On 02/21/2017 12:21 PM, John Porter wrote:
Sadly, I have not explained very well have I, as no one seems to grasp what I am on about.

The middleware does not need to know about the exchange at all, it is only responsible for receiving a Message and returning a Message. I am currently coding up the example to show you all.

Woody, for your scenario, the RequestMiddlewareInterface would return a ResponseInterface instance, this is why the return value is only typed to MessageInterface; to allow that short circuit to be returned, so that the stack can terminate.

I think my example (with tests) will highlight this better than I can explain; bear with me.


On 21 February 2017 at 18:13:35, Michael Mayer (mich...@schnittstabil.de <mailto:mich...@schnittstabil.de>) wrote:

As far as I can see, the essential difference between PSR-15 and your proposal is about the responsibility for dispatching the next middleware: 1. with your version: it is determined at /compile time/, by implementing the appropriate interface; thus the stack should be responsible for it only. 2. with the PSR-15 version: it is determined at /run time/, thus the stack and the middleware are responsible for dispatching the next middleware.

Django, StackPHP and Guzzle for example, have chosen an approach which seems to align better to your version. In essence, their middlewares could be typed as:

|(RequestInterface -> ResponseInterface) -> (RequestInterface -> ResponseInterface)|

Or, if we want to use PHP interfaces only, then we could type them:

|interface ExchangeInterface
{
public function __invoke(RequestInterface $request): ResponseInterface;
}

interface MiddlewareInterface
{
public function __invoke(ExchangeInterface $next): ExchangeInterface;
}|

At first glance that could solve your issues with the current PSR-15, the /exchanger/ does not seem to be responsible for dispatching the next exchanger and middlewares are simple exchange factories. And moreover we do not need middleware dispatchers anymore.

Unfortunately that isn't very attractive in PHP, a middleware would look like:

|class UnicornMiddleware implements MiddlewareInterface
{
public function __invoke(ExchangeInterface $next): ExchangeInterface {
return new class($next) implements ExchangeInterface {
private $next;

public function __construct($next)
{
$this->next = $next;
}

public function __invoke(RequestInterface $request): ResponseInterface
{
return (($this->next)($request))->withHeader('X-PoweredBy', 'Unicorns');
}
};
}
}|

That's probably one of the reasons why StackPHP uses `__construct` and Guzzle uses closures. But even worse, the inner ExchangeInterface instance is still responsible for dispatching the next middleware :(

Are the PSR-15 interfaces so bad? From the perspective of a functional programmer, we can do some simple currying <https://en.wikipedia.org/wiki/Currying> to change the typing to get better interfaces:

|(RequestInterface -> ResponseInterface) -> (RequestInterface -> ResponseInterface)
// using curry:
(RequestInterface -> ResponseInterface) -> RequestInterface -> ResponseInterface
// and again:
((RequestInterface -> ResponseInterface) -> RequestInterface) -> ResponseInterface
|

Again, if we use PHP `interfaces` only, the last version could look like this in PHP:

|interfaceExchangeInterface
{
public function __invoke(RequestInterface $request): ResponseInterface;
}

interface MiddlewareInterface
{
public function __invoke(ExchangeInterface $next, RequestInterface $request);|
|}|

Aside from the parameter order, the similarities to the PSR-15 version are already obvious (Sadly, the names and implied contracts are very different and PSR-15 does not describe a functional middleware pattern anymore :cry: ).

Anyway, the example above becomes much simpler with the current PSR-15 interfaces:

|class UnicornMiddleware implements ServerMiddlewareInterface
{
public function process(ServerRequestInterface $request, DelegateInterface $delegate) { return $delegate->process($request)->withHeader('X-PoweredBy', 'Unicorns');
}
}|

Thus I believe your proposal does not fit better to the middleware pattern.

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/vCKxyraoqnc/unsubscribe. To unsubscribe from this group and all its topics, send an email to php-fig+unsubscr...@googlegroups.com <mailto:php-fig+unsubscr...@googlegroups.com>. To post to this group, send email to php-fig@googlegroups.com <mailto:php-fig@googlegroups.com>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/b0794cd8-089a-4753-bbf5-9a3d0e833b06%40googlegroups.com <https://groups.google.com/d/msgid/php-fig/b0794cd8-089a-4753-bbf5-9a3d0e833b06%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscr...@googlegroups.com <mailto:php-fig+unsubscr...@googlegroups.com>. To post to this group, send email to php-fig@googlegroups.com <mailto:php-fig@googlegroups.com>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/etPan.58ac8529.344f83e6.2227%40designermonkey.co.uk <https://groups.google.com/d/msgid/php-fig/etPan.58ac8529.344f83e6.2227%40designermonkey.co.uk?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to php-fig+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/8f66492b-db0c-8017-f758-0f14fdce90fd%40garfieldtech.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to