On Friday, April 21, 2017 at 10:12:12 PM UTC+2, Rasmus Schultz wrote:
>
> Hi Michael :-)
>
> > As a handler objects holds a reference to the next handler object, it 
> is not reusable anymore.
>
> Well, the instance itself isn't "reusable" - but the code is, that's what 
> matters, isn't it?
>

Not always, I believe the current PSR-15 is superior in a React 
<https://github.com/reactphp/react> environment. On first glance:

   1. less memory usage
   2. better GC 

 – but maybe I'm wrong on that.
 

> Callables in PHP are also objects, and a quick benchmark indicates 
> literally no difference between a closure and an idempotent functional 
> component - the creation overhead is more or less identical:
>
> https://gist.github.com/mindplay-dk/0d4e073179fedb9bb10663c3ffe22336
>

At first, you did it wrong :-) – see my gist comment. Secondly, you've 
mixed my two arguments, but my main concern was about naming things right, 
not about performance. To me Middleware is a pattern of Functional 
Programming:

   1. Middlewares are defined by lambdas/__invoke/…
   2. Middlewares use Continuation-Passing Style (CPS) 
   <https://en.wikipedia.org/wiki/Continuation-passing_style>: 
   $next encapsulates the remaining computation

You know, I like the pattern you are proposing, but calling it Middleware 
does not fit to me: it is pure OOP. Calling it Middleware might sound sexy, 
but would need intense mental gymnastics to see a FP-Pattern.

I'm only aware of shelf <https://pub.dartlang.org/packages/shelf> in the 
Dart world:

Middleware can be thought of as a function that takes a handler and wraps 
> it in another handler to provide additional functionality.


Hence, I'm not sure which Dart framework you are referring to (Btw, that is 
the same idea as Pythons Django 
<https://docs.djangoproject.com/en/1.11/topics/http/middleware/> Middlewares, 
only the names differ).

Applying this idea to PHP, one probably comes up with these interfaces:

interface RequestHandler {
    function __invoke(ServerRequestInterface $request);
}

interface Middleware {
    function __invoke(RequestHandler $handler) : RequestHandler;
}

That Middleware interface also solve some __constructor issues, but 
obviously come with other disadvantages.

*tl;tr:* I love that pattern, but calling it Middleware sounds wrong.

About all your one-to-many successor concerns: I fully agree, and a Router 
is a good example which should not be implemented as a Middleware and 
moreover should not dispatch Middlewares. The current design I'm using, can 
be pictured as:

<https://lh3.googleusercontent.com/-aKVlR3yNCRk/WP3g7-1mscI/AAAAAAAAAGw/CRqiwo7l0SEWSN2KQShftL0mljCTsF47QCLcB/s1600/RequestHandlerVsMiddleware.png>


IMO, treating everything as Middleware is just as wrong as treating 
everything as RequestHandler. I want to use Middlewares to implement 
cross-cutting concerns, which justifies that they sit in the middle of the 
application stack, e.g. the LogMiddleware in the picture above. However, it 
would be strange to create multiple LogMiddleware instances: we have only 
one single log file. And it would also be strange, if LogMiddleware has a 
successor property, because that way it could only log things of a single 
successor.

Michael

-- 
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/267f5a3d-2e5a-4db3-b41e-f90cdf149e37%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to