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.