If I had to summarize all of my thinking about this subject into a single
statement, it would be this:

The interface that describes any component that takes a Request and must
return a Response, is the most fundamental transaction we can meaningfully
describe.

That is, at the highest level, the processing of any server-side transation
can be described in this way - no matter what else happens below that
level, how you describe it, or what other details of the net transaction
you may be able to describe with other interfaces, this is the fundamental.

Starting with middleware and ignoring that fact would be remiss, not least
because we've already seen numerous examples of how this same contract
occurs in in at least three or four cases within the scope of (the proposed
concept of) middleware.

Michael Mayer has already started the PSR for this interface, and has
already indicated he would agree to reduce the scope of the first PSR to
just the interface required for PSR-15 middleware.

We need to do this, and I think we could get through the process rather
quickly - the interface and the proposal should be trivial.

Actually, the only thing we're still debating is the naming of the
interface and method, which seems to be something people have different
ideas about - perhaps because everyone has encountered different use-cases
for this interface.

I've used it for several things myself, including middleware,
dispatchers/delegates and controllers - all of these could be said to
"handle" or "process" a request in some way, the preferred terminology is
probably largely a matter of opinion, and your personal relationship and
experience with those words.

One thing I would submit is that, in the name of moving forward, I'd like
us to stick with "process" as the method-name, as it is in the
DelegateInterface in PSR-15 at the moment - because this will create the
least possible disruption. Existing middleware would just need to change
the implements-clause from DelegateInterface, nothing else - we'd be able
to move past this breaking change and towards a final PSR-15 with as little
detour as possible.

As for the name of the interface itself, that's not as important to me.
Earlier I proposed "ControllerInterface", which was not well received, and
later I proposed "HandlerInterface", which I think sounds general/neutral
enough to cover all the use-cases. The current proposal says
"ActionInterface", which I think is just as ambiguous as
"ControllerInterface".

I'd love to hear other suggestions.


On Sun, May 21, 2017 at 10:43 AM, Michael Mayer <mich...@schnittstabil.de>
wrote:

> For clarification: I'm still undecided about the usefulness of the two
> modifier interfaces (described in this thread as "$request = $foo
> ->modify($request);" and "$response = $foo->modify($response);"). I've
> added them to the hms proposal
> <https://github.com/http-message-strategies-interop/fig-standards/blob/http-message-strategies/proposed/http-message-strategies/http-message-strategies-meta.md>
>  to
> make them discussable and to explore their pros and cons. As Rasmus
> suggested, they will be removed within the next few days because the
> ActionInterface/HandlerInterface can stand on its on.
>
> On Saturday, May 20, 2017 at 10:33:33 PM UTC+2, Matthieu Napoli wrote:
>
>> Rasmus:
>>
>> I can see the handler-interface having 3 uses in the context of PSR-15:
>>> …
>>> 3. As type-hint for the "final" handler supported by many dispatchers.
>>
>> 3. I agree this is a bit of an ugly detail and it would be better if we
>> could do without, but honestly this is just a detail, and it works, and
>> it's not really a practical problem, I don't see how a PSR would matter here
>>
>
> That PSR would also allow interop of routers, controllers and final
> handlers, and indeed solve practical problems, e.g. if you use it with your
> pipe function:
>
> // diff in pseudo code:
> - function pipe(MiddlewareOrHandler[] stack) : Middleware {}
> + function pipe(Middleware[] stack, Handler $final) : Handler {}
> - function router(array routes) : Middleware {}
> + function router(array routes) : Handler {}
>
> Thus you do not need to fabricate handlers like the one at your
> Router::dispatch
> <https://github.com/stratifyphp/router/blob/779a77b6b8078fa3cb2fe86a3361c43b06df94e0/src/Router.php#L83-L85>,
>  and
> the code of your example becomes bit more explicit:
>
> $application = pipe([
>     ErrorHandlerMiddleware::class,
>     ForceHttpsMiddleware::class,
> ], prefix([
>     '/api/' => pipe([
>         HttpAuthenticationMiddleware::class,
>     ], router([
>         '/api/articles' => /* controller */,
>         '/api/articles/{id}' => /* controller */,
>     ])),
>
>     '/' => pipe([
>         MaintenanceModeMiddleware::class,
>         SessionMiddleware::class,
>         DebugBarMiddleware::class,
>     ], router([
>         '/' => /* controller */,
>         '/article/{id}' => /* controller */,
>     ])),
> ]));
>
> As you can see, there is no essential difference for the end user setup.
> Although, we do not need to create those meaningless $next delegates: the
> prefix and router functions return them.
>
> And yes the router will be invoked with a $next, but IMO that's a good
>> thing: the router can call $next if the URL doesn't match any route
>> <https://github.com/stratifyphp/router/blob/master/src/Router.php#L58-L63>.
>> That allows, for example, to use several routers in a single pipe (e.g. if
>> you have modules).
>>
>
> I disagree, that's not a good thing, this means $next would be used
> differently by different middlewares:
> For example for your HttpAuthenticationMiddleware, calling $next means:
> everything is fine; lets carry out the real task and if that fails I will
> try to handle that.
> For the router you're suggesting, calling $next means: something went
> wrong; lets delegate the task to someone else and if that fails I do not
> care.
>
> Thus, using $next to signal "404 Not Found" is bad for many reasons:
> 1. 404 is one error of many, e.g. what about routing related errors like
> "405 Method Not Allowed" and "415 Unsupported Media Type"?
> 2. What kind of *final handler* do I need to dispatch middlewares? For
> router middlewares I probably want a *NotFoundHandler*, but for a
> controller action I probably want a handler which returns a plain response
> object.
> 3. Because of 2., you need some conventions, i.e. framework specific
> conventions(!), which means it would neither be possible to reuse your
> '/api/' middleware stack across multiple frameworks nor and more
> importantly your RouteMiddleware itself.
>
>
>> And by the way this is a bit what Slim and IIRC Zend Expressive do: route
>> handlers can be controllers or can be pipes, that's how you can add "route
>> middlewares" (I hope I'm not wrong here).
>>
>
> Slim controller actions
> <https://www.slimframework.com/docs/concepts/middleware.html#how-do-i-add-middleware>
>  are
> not middlewares, they get an $args argument instead of a $next.
> Zend Expressive and Zend Stratigility:
>
> $app->pipe('/', function (ServerRequestInterface $request,
> DelegateInterface $delegate) {
>     return $delegate->process($request);
> });
>
> $app->pipe('/', function (ServerRequestInterface $request,
> DelegateInterface $delegate) {
>     $response = new Response();
>     $response->getBody()->write('Wtf?');
>     return $response;
> });
>
> Zend Expressive is based on Stratigility and returns a 404 for '/'.
> Interestingly, Zend Stratigility itself returns a 200 (content: 'Wtf?') –
> yes, exactly the same code snippet can be used in both frameworks.
> IMO, these setups are hard to debug, and to me, it is another reason why I
> dislike routers/controllers which call $next: I can never be sure what
> $next will return (without further knowledge about the framework).
>
> --
> 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/B3jtdJA7-6w/unsubscribe.
> To unsubscribe from this group and all its topics, 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/9fb17b11-95da-4b42-9737-e4464b5c090f%40googlegroups.com
> <https://groups.google.com/d/msgid/php-fig/9fb17b11-95da-4b42-9737-e4464b5c090f%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.
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/CADqTB_iY4VBOkj5orto%3DTr51s668yMWwsxM0%2BKr8Yg7V6_vuaw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to