On Sun, Jun 19, 2016 at 2:55 PM, Alessandro Pellizzari <a...@amiran.it> wrote:
> On Sun, 19 Jun 2016 09:31:30 -0500
> Woody Gilk <woody.g...@gmail.com> wrote:
>
<snip>

> > When
> > the middleware is responsible for calling the next middleware, you
> > gain specific benefits:
>
> Yes, but it's also a pattern most modern languages are getting away
> from. Go takes ResponseWriter,Request. Rust takes Request,Response.
> Django on Python takes Request,Response
>
> Basically the only other language using next is Javascript.

You're making the assumption that approaches never evolve.

As somebody who ported Connect/Express to PHP, I'll weigh in on why I've adopted
the argument, and why I think it's an important part of the interface.

When you don't have the argument, the way to build your middleware application
is to pass the stack/application to each middleware via either the constructor,
a setter, or a property. While DI containers help with this, it requires that
you know all paths through the application and define this via the dependency
graph. Many frameworks thus have a conventions-based approach for injecting the
stack into middleware (e.g., the application injects itself as a property),
which means that middleware is tied to specific middleware stacks. When you have
a single, language-supported approach, such as WSGI in Python or Rack in Ruby,
then this isn't a problem. When you don't, such as in JS or PHP, it *is* a
problem, as you cannot re-use middleware between the different stacks.

Connect/Express could have taken this approach, but instead opted for passing
the stack as an argument to the middleware during invocation, via a "next"
argument. This approach meant that when Express split from Connect, *middleware
written for Connect continued to work with Express, and vice versa*.
Interoperability works best when it's not based on conventions, but rather
signatures and strict types. Passing the stack as an argument enforces exactly
that.

Another thing to consider is: does your middleware really need to store a
reference to the stack *as a property*? In particular, does this make sense in
an async environment? In Connect/Express, your middleware likely shouldn't keep
a reference to the stack, *as it will change between requests*. When we consider
that one target for PHP middleware are async libraries such as ReactPHP and
Icicle, we definitely want to consider this.


> > - being able to terminate the request
>
> This is done through exceptions.

Exceptions should be used for exceptional circumstances, not expected
application workflows.

<snip>

> So, the only thing you lose is the ability to change the Request,
> which, as I say, is a plus, not a downside.

It's a downside. One aspect of middleware is that you can *nest* middleware in
order to re-use it. As such, I can write middleware that routes for:

- /news
- /news/:date
- /news/:date/:article

and nest it in another application such that it attaches and triggers when under
the path "/devteam", and it will now respond to the following:

- /devteam/news
- /devteam/news/:date
- /devteam/news/:date/:article

*without needing to change any routing internally*. The reason it can do this is
that the middleware stack can strip the subpath "/devteam" before passing the
request on to the nested middleware.

Removing this ability would make such nesting far more difficult, making re-use
less palatable.

-- 
Matthew Weier O'Phinney
mweierophin...@gmail.com
https://mwop.net/

-- 
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/CAJp_myUDUmar2uMwVBSVHfwCsFS7LybUvfrw2C4YoXivKBv%2Bxw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to