-
Notifications
You must be signed in to change notification settings - Fork 90
Suggestion for '<Dispatch|Route>Middleware::class' in 3.0alpha #220
Comments
It is explained here: zendframework/zend-expressive#548 (comment) They are "Virtual" classes; they're FQCNs that do not resolve to actual classes/interfaces. It's a design decision that has been made. In the past, strings were used as you propose. Using FQCNs felt better as some of them are leftovers for backward compatibility and a smooth transition from expressive 2. In PHP Stan you can ignore specific error messages. |
I got the idea of 'virtual classes'... but still thinking, is there not a better solution ? I remember being confused by the At first sight, the idea to add a I read @weierophinney comment on zendframework/zend-expressive#548 (comment), and I understand the reasons for aliasing (migrations...), but still think if the idea is to provide built-in aliases, let's define them as constants somewhere (promote IDE friendliness and phpdoc). IMO, at least if it does not happen in expressive, I would recommend to not use 'virtual classes' in the skeleton. It's a starter, why would we have a set up exclusions for static analyzers ? BTW: For phpstan that's what I'm doing already, see here but what about others (psalm, ea inspections...). |
Exactly this. Either way leads to confusion. There should have been a comment above the classes explaining exactly this.
I like this idea. Add a few constants in the Application class with a comment to explain it. That should prevent the confusion for developers and static analyzers. /cc @weierophinney thoughts? |
I'm not against it, though I struggle with the following:
So, my proposal is this:
Thoughts, @belgattitude and @xtreamwayz? |
That looks like a good solution to prevent more confusion amongst users and keep the IDEs happy at the same time. |
looks good. just need a little space to think about it. I'll let you know my thoughts in a day. |
A few notes for reflexion :
In V2, V3 looks more natural to me. While migrating I've just replaced All that to say that I'm agree with your concern: I'm probably shamefully wrong on this ;) just expressing my experience while migrating.
In v2 they were somehow in 'Application' (DISPATCH_MIDDLEWARE, ROUTING_MIDDLEWARE). Yes it can make sense that they belongs to their containers. My only concern... I would not resolve the constants to FQCN... they aren't. Just "built-ins 'expressive'-specific keys" (sorry for my poor wording here).
IMHO, let's make it clear they are built-ins constants, not classes. So my proposal:
But please, just remember I'm by no way expert on this matter. So feel free to make what you think is best. BTW I love expressive and especially the clear distinction between middleware and handlers. I must admit that I didn't feel comfortable with middleware/action where both could be anything ... Thanks a million to make it ! :D |
👍 |
This is a planned change for v2.2. As we prepare new major revisions, once the API stabilizes, we plan a new minor release of the existing major version in which we perform deprecations and backports in order to provide a path for users to prepare their applications for the new major version. One of the changes already staged is pushing the I'm not sure I like the idea of constant values that resolve to strings like At this point, we need to make a choice, and the choice needs to be consistently applied. We either go with constant values that look like class names, or we go with the Considering we can alleviate the semantic meanings with well-crafted names, the second choice (string values that do not look like FQCN) is likely the best in terms of preventing user confusion, much as I dislike it. 😄 I'll work on that in the coming days. |
Fully agree ;) If it helps, just a little recap with built-ins I might use as a developer (excluding virtual classes like ApplicationPipeline...):
The NotFoundHandlerFactory :
(Important to remember usage in v2 of And why not (for consistency) ?
I must admit I'm not really 100% happy with it... I'll think overnight and let you know. Thanks @weierophinney ! |
on my way back home I though about something that you may like (or dislike ;) What about using real classes instead ? Imagine: <?php declare(strict_types=1);
namespace Zend\Expressive\Resolver;
/**
* Example of documentation:
* RouteDispatcher class is used to resolve the route dispatcher
* middleware in zend-expressive applications... .
* (we can add here things like deprecation, usage, notes...)
*/
final class RouteDispatcher {};
Pros (most of the things apply for constants too)
Cons
Notes
Would it be a good option ? @xtreamwayz @weierophinney |
Honestly, I think that will be more confusing for developers diving in trying to understand the code:
It's that first point that is really sticky; it's the same issue with any of the solutions proposed. "Virtual classes" that do not resolve to a real class: developers are confused about why. Empty final classes that have no relation to the final service loaded: developers confused about the relation between them. I think constants are the least offensive option here. We can even make them namespaced constants, which means no new classes to import (i.e., they will not be defined on a factory which you might end up not using if you override the service definition), no unexplained or unexpected relations to other classes (e.g., defining them in something like |
Then it looks perfect to me ! thanks a lot for taking your time on this. |
Per the discussion on zendframework/zend-expressive-skeleton#220, this commit converts virtual service names to constants. In each case, the original resolved value of the virtual class name is used as the constant value, but the config provider and factories now refer to the constants instead. Additionally, the `RouterResponseInterface` constant was discovered to be no longer needed, due to the extraction of route-related middleware to the zend-expressive-router package.
The linked zendframework/zend-expressive-router#50 demonstrates this, and I've also provided a patch at zendframework/zend-expressive#551 that does similarly in the zend-expressive package. The first uses CAPS_CASE values, while the second uses values that look like class names; this allows existing references to continue to work, while new implementations will use the constants themselves. |
I'll update the skeleton once the zend-expressive pull request is merged. |
Fixed in #222 |
@belgattitude Thanks for the reminder; I'll make sure that zend-expressive has a constant defined that aliases to the new zend-expressive-router variant. Good catch! |
The constants both exist in the zend-expressive package as of its 3.0.0alpha6 release. What #222 did was refer to the But it turns out that in all containers we support, aliases resolve to their final service, and we then check to see if the service has already been created. This means that if you request a service by its alias name, you'll get the same instance as if you had retrieved the service to which the alias resolves. As such, if your pipeline still refers to the legacy As such, we actually didn't need to update the skeleton to refer to the |
@weierophinney Fantastic ! No issues after update to alpha7&8. |
Is there is a better way to resolve
DispatchMiddleware
andRouteMiddleware
in theconfig/pipeline.php
?See:
IMO I would not rely on the
::class
feature to avoid writing a string, but introduce some constants in expressive to know what we're dealing with.Another option is to write the FQCN as a string (i.e
$app->pipe('Zend\Expressive\Middleware\DispatchMiddleware')
). Not very fond of this, but at least code checkers, phpstan... won't complain.BTW: Bravo for the release !!!
The text was updated successfully, but these errors were encountered: