I may be re-treading a previous discussion, but as I read the discussion, I begun to ask: why?
Why do we need a PSR for this at all? HTTP request/response handling/filtering is very integral and ‘internal’ to a framework/library. There are many ways to approach this problem (as we have clearly seen), and they are largely self-contained within, and integral to, the framework. PSR-7 (as an example) makes complete sense because it enables inter-op between frameworks, libraries and projects. But this proposal — and PSR-15 along with it — is pushing the boundary of ‘inter-op’ and into ‘dictation’. I feel like we’re beginning to build an 'interface-framework’, which, in my humble opinion, is overstepping the role and purpose of the FIG. Let frameworks be themselves, and let them innovate. There’s no need for us to tell them how to do things like this. What do you think? John On Apr 24, 2017, at 9:47 AM, Rasmus Schultz <[email protected]<mailto:[email protected]>> wrote: I'd like to revive this thread. I got to thinking about this again after opening this can of worms: https://groups.google.com/d/msg/php-fig/B3jtdJA7-6w/jzgSPrpYAQAJ What I'm thinking is, a PSR for message operations is more or less a no-brainer either way - and regardless of the mentioned can of worms, we need at least the request/response interface, which I'm now going to refer to as a "handler". Going ahead with a custom definition of that interface as part of PSR-15 would be a huge mistake, as this interface is extremely general - and whether or not it's useful as a means of implementing middleware by itself, it's useful and necessary for many other things. I'd propose to dub this "HTTP Message Operations", and I'd propose it include the following: interface HandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface; } interface RequestFilterInterface { public function filterRequest(ServerRequestInterface $request): ServerRequestInterface; } interface ResponseFilterInterface { public function filterResponse(ResponseInterface $response): ResponseInterface; } All of these interfaces are designed for server-side message operations - client-side processing would be out of scope for this, it's a whole other can of worms involving async etc. The request and response filter interfaces are useful for pre-processing requests and post-processing responses - I believe these operations are just as basic as the request/response handler. I have similar interfaces on several projects currently myself. I don't think it's hard to see the usefulness of standardizing on these? I also don't think the details could possibly warrant year-long ongoing discussion about minute details? These interface are about as basic as anything can get - the most we can quibble about would be interface/method-names, e.g. mostly bikeshedding. I'd like to write up a formal proposal if there is interest, unless any of you have really good reasons why this shouldn't exist, or why it wouldn't for some reason be a "slam dunk"? I know most PSRs are notoriously never a slam dunk, but it's hard for me to imagine what else we could quibble about over something this simple? Let me know what you think please. (and let's keep discussions about middleware out of this thread, if possible.) Thanks, Rasmus On Thu, Jan 26, 2017 at 10:00 PM, Rasmus Schultz <[email protected]<mailto:[email protected]>> wrote: > Maybe it could be used also for this purpose, instead of something used > exclusively inside a middleware. Yep - I made efforts to convince the PSR-15 team that we should actually wait and standardize this first, but it's already been forever and nobody wants to wait any longer than necessary for this one... That said, I have a hard time imagining how anyone would manage to come up with ways to complicate the discussion about an interface this simple. It doesn't need a long description or lengthy discussion, I think - it's the highest-level of request/response abstraction you can have, but yeah... nobody wants to wait ;-) On Thu, Jan 26, 2017 at 9:54 PM, Oscar Otero <[email protected]<mailto:[email protected]>> wrote: The PSR-15 DelegateInterface uses this signature: https://github.com/http-interop/http-middleware/blob/master/src/DelegateInterface.php Maybe it could be used also for this purpose, instead of something used exclusively inside a middleware. El 26 ene 2017, a las 20:08, Rasmus Schultz <[email protected]<mailto:[email protected]>> escribió: We have support both for path-matching (via attributes provided by the router) and multiple action-methods in our controller base-class - this design doesn't prevent either of those things. I reckon you're taking the term "controller" as meaning something other or more specific than the definition I use: anything that takes a request and produces a response is a controller. How the request is interpreted, or what further steps or external dependencies are involved in creating the response, is not defined, nor relevant. If the term "controller" is confusing, try the term "dispatchable" or "request dispatcher". Early on in the PSR-15 process, the same interface signatures was proposed as the interface for dispatching a middleware-stack - having an interface that is this generic for something that is that specific, is silly. This interface can be usefully applied to an endless number of request/response scenarios - anything from a single controller, middleware-stack or micro-framework, all the way up to complex frameworks like Drupal or WordPress. I find it quite unopinionated - you can put behind that interface any kind of controller-like concept you can imagine, there is absolutely nothing about this interface that implies anything more than "takes a request, produces a response", which will fit just about any top-layer of any PSR-7 based architecture you can dream up, even clients for that matter. It seems a lot of you assign a lot more meaning and intent to this than I was trying to convey - being able to build stand-alone controllers (or base-classes) which could be supported by routers, is just one use-case. There is absolutely nothing mandating that strategy over any other strategy. I obviously shouldn't have used the term "controller" - but to me, because the term is so overloaded, it really doesn't mean anything specific. For example, the term "controller" is common in client-side view/model-abstractions, and "front controller" is common when describing a catch-all "index.php", which is pretty far from something live a Drupal controller. The term to me is about as open-ended as anything. I'd be fine with any other term, though personally I think "dispatcher" might be even more overloaded - everything gets dispatched, HTTP requests, API requests, methods, functions, closures.... What matters is that almost anything that uses PSR-7 under the hood could potentially implement this interface on the server, which paves the way for very high-level architecture, e.g. higher than middleware, where the middleware runner itself could be described in the abstract at this level. Currently those top layers have nothing formally in common and don't compose well, besides, of course, as middleware, but then you've already made the decision to use middleware, and that *does* imply architecture. On Jan 26, 2017 19:03, "Matthew Weier O'Phinney" <[email protected]<mailto:[email protected]>> wrote: On Tue, Jan 24, 2017 at 1:14 PM, Rasmus Schultz <[email protected]<mailto:[email protected]>> wrote: >> While I can certainly see the value in the architecture this would imply, >> it's by no means the only architecture > > I disagree that this implies architecture. > > "takes a request and returns a response" is in my opinion the least > opinionated, most open-ended definition you can have of a controller - in my > opinion, it does not imply architecture, at all. You're completely free to > use traits, composition, base-classes, external services, registries, > dependency-injection, middleware - anything you can dream up, the only > requirement is that you ultimately take a PSR-7 request and produce a > response, which, ultimately, if you're using PSR-7, you're going to, one way > or the other. It does imply architecture, however: one controller, one action. Most MVC systems I've surveyed or participated in maintaining provide a way to map multiple actions to a single controller, which necessarily means multiple entry points: ```php class SomeController { public function listAction($request) { } public function fetchAction($request) { } public function createAction($request) { } public function deleteAction($request) { } } ``` Sometimes this means standardization of method names (as detailed above), sometimes there is a 1:1 relationship between an action and the method name, sometimes there's a single entry method that then dispatches to the appropriate method based on the action matched, etc. Additionally, I've seen systems that will pull path matches and pass them as discrete arguments to the controller/action, often with the request as a catch-all at the end of the list: ```php // Route: /article/:id public function update($id, $request) { } ``` I personally have been pushing folks to follow the "1 route, 1 controller" paradigm, which is what your proposal suggests, but that's a _suggestion_; _requiring_ it via a standard, however, means any implementing library _requires_ that approach, which I suggest would limit adoption. -- Matthew Weier O'Phinney [email protected]<mailto:[email protected]> https://mwop.net/ -- 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/HD5meon7TX0/unsubscribe. To unsubscribe from this group and all its topics, send an email to [email protected]<mailto:php-fig%[email protected]>. To post to this group, send email to [email protected]<mailto:[email protected]>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/CAJp_myWsLaaPKMaT%3DwG1OvDjsw9KH7ZiEpWgvFKo2%2BfiVo55UA%40mail.gmail.com. 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 [email protected]<mailto:[email protected]>. To post to this group, send email to [email protected]<mailto:[email protected]>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/CADqTB_i1adq_apAOnBc0PJguXmDz1dbQbZ1M3EE45k4HJCOnBQ%40mail.gmail.com<https://groups.google.com/d/msgid/php-fig/CADqTB_i1adq_apAOnBc0PJguXmDz1dbQbZ1M3EE45k4HJCOnBQ%40mail.gmail.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 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/HD5meon7TX0/unsubscribe. To unsubscribe from this group and all its topics, send an email to [email protected]<mailto:[email protected]>. To post to this group, send email to [email protected]<mailto:[email protected]>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/D620C423-EDB5-4247-8616-87A1347915E9%40gmail.com<https://groups.google.com/d/msgid/php-fig/D620C423-EDB5-4247-8616-87A1347915E9%40gmail.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 [email protected]<mailto:[email protected]>. To post to this group, send email to [email protected]<mailto:[email protected]>. To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/CADqTB_i%2Bu6oEeynKUzMYM%3Ds90bMuBern8epFMCxeNn6BQyWdhA%40mail.gmail.com<https://groups.google.com/d/msgid/php-fig/CADqTB_i%2Bu6oEeynKUzMYM%3Ds90bMuBern8epFMCxeNn6BQyWdhA%40mail.gmail.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 [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/443F69E7-8049-48CB-BE7E-A6508B2AE06D%40buffalo.edu. For more options, visit https://groups.google.com/d/optout.
