zendframework / zend-mvc

Mvc component from Zend Framework
BSD 3-Clause "New" or "Revised" License
105 stars 90 forks source link

[ZF3] Simplifying MvcEvent #177

Open GeeH opened 8 years ago

GeeH commented 8 years ago

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7185 User: @bakura10 Created On: 2015-02-05T15:11:06Z Updated At: 2015-11-06T21:25:43Z Body Hi everyone,

I think I may already talked about that, but I'd like to know if someone has started thinking about how can we simplify the dispatching process (is this the middleware solution?).

I have a lot of pain points with current MvcEvent, especially because it aggregates so many things and plug into so many different events that it makes it hard to work with.

For instance, the getViewModel is confusing. It seems that a lot of listeners inside the framework (or third-party module) set the view model inside result (using setResult), but at some point of the process, it gets magically injected using setViewResult (but why only at some point of the process, and not as soon as we create a view model?).

The same for exception. Currently, the framework set the exception into a param. This is a bit fragile, because a param is just a param. A listener could possible remove the param, and subsequent listeners could have unexpected results.

I don't have any idea of how it could work, but the fact that the MvcEvent is nearly transferred from start to bottom, always make me ask questions like: "ok, so at this point... do I have a view model? if so, where it is stored exaclty?" or "what kind of data "getResult" will return me here?".

If anyone has worked extensively with listeners and hook into the dispatch process, please share your experience and pain points, I'm sure it would help us and other contributors.

ping @weierophinney @Ocramius


Comment

User: @stefanotorresi Created On: 2015-02-05T17:53:24Z Updated At: 2015-02-05T17:53:24Z Body I feel your pain, but the whole point of the event is that it's a message passed along between the various components, so I guess the fact that it holds different data in different phases of the cycle is completely intentional.

if I had to strip it down to the bare minimum, I would say that the event should only aggregate request and response (immediatly injected since the start of the cycle), a reference to the last exception (with a setter that injects previous exceptions each time is invoked), and finally a KVS of user parameters (which should not be things crucial to the execution tho, just optional things to pass around listeners).

also, I would rather have the rendering process using a completely different event cycle, because the main cycle should always be failsafe and be at least capable to provide a sane response, instead of as it is now, where errors occurred during rendering may also affect the rendering of the error themselves.


Comment

User: @bakura10 Created On: 2015-02-05T17:58:46Z Updated At: 2015-02-05T17:58:46Z Body The rendering process is already handled by another event (ViewEvent), but it shares the same complexity as MvcEvent. But the point is: do we need the request in ViewEvent? Do we need the view model (rendering purpose) in the MvcEvent?

Maybe I'm missing some use cases, but couldn't we have something like that:

  1. Application triggers RoutingEvent.RESOLVE_ROUTE (RoutingEvent being a new event that is not aware of ViewModel, but only what it needs to do its work).
  2. Then Application triggers MvcEvent.CONTROLLER. ... and so-on...

If we are able to split the event in smaller events, then we could have less side-effects and more focused events.


Comment

User: @Ocramius Created On: 2015-02-05T18:00:58Z Updated At: 2015-02-05T18:00:58Z Body

The rendering process is already handled by another event

That is a different concern: that's just because the view layer as it stands is a terrible mess.


Comment

User: @stefanotorresi Created On: 2015-02-05T18:12:58Z Updated At: 2015-02-05T18:12:58Z Body Yes there is another event, but the two cycles are tied together, Zend\Mvc\View\Http\DefaultRenderingStrategy listens to \Zend\Mvc\MvcEvent::EVENT_RENDER, and this is what I'd like to get rid of :p

If we consider the middleware approach suggested by @weierophinney, I imagine rendering would happen during a middleware dispatch, being just a body being created and injected into a response.

I guess the mvc cycle could just turn into a much simpler control cycle that just invokes middlewares, which in turn trigger other event cycles (routing, rendering, whatever). That would allow the base application control event (say a MiddlewareEvent) to only have those things I mentioned: request, response, errors, and a kvs.


Comment

User: @bakura10 Created On: 2015-02-05T18:16:57Z Updated At: 2015-02-05T18:16:57Z Body Ha yes I forgot the EVENT_RENDER. Definitely bad that MvcEvent coordinates this too. Definitely.


Comment

User: @RalfEggert Created On: 2015-04-22T08:56:31Z Updated At: 2015-04-22T08:56:31Z Body Should be marked for ZF3 milestone, shouldn't it?


Comment

User: @danizord Created On: 2015-04-22T16:00:57Z Updated At: 2015-04-22T16:00:57Z Body The mess and complexity is caused by the fact that events are mutable and we take advantage of it. Not sure if this is possible, but it would be great to have ZF3 lifecycle working with immutable events.


weierophinney commented 4 years ago

This repository has been closed and moved to laminas/laminas-mvc; a new issue has been opened at https://github.com/laminas/laminas-mvc/issues/25.