On Friday, April 21, 2017 at 1:37:48 PM UTC-4, Rasmus Schultz wrote:
>
> > How would the container know which $kernel to use in the constructor
> for the object at $id? This looks nice, API-wise, but it is ignoring how
> this object would actually be constructed.
>
> Of course this "skips the constructor part", that's what the DI container
> is for - if you're using one, that's where construction happens.
>
> The current proposal doesn't deal with the creation of middleware either,
> only with the dispatch.
>
> So I'm not sure I follow.
>
>
Since construction using this model implies that each middleware has to
know about the previous, it makes sense to consider how a DI container
would be able to handle that case. Unless you can show how it can easily be
done, I think it makes this proposal difficult to swallow for people who
want to be able to middleware as a basis for a framework.
> > We used Stack Builder to help try and solve those problems. It still
> seemed messy and I was never very happy with it.
>
> That's pretty abstract, so can you point to (legacy) code or discussions,
> or illustrate with code examples maybe?
>
It looks like I never completed STACK-1, but it comes down to the rules of
building a Stack middleware:
1. Extend HTTP Kernel Interface
2. Constructor MUST take an HTTP Kernel Interface as the FIRST argument
This worked for the simple case you are describing where you can have full
control over every piece of middleware and you can construct it inline.
Since we had the constructor rule defined, we were able to make Stack
Builder construct a stack somewhat dynamically. It wasn't, however, able to
leverage the containers very easily to build out any dependencies the
middleware themselves might have.
Both Laravel and Drupal 8 started to use Stack PHP. Laravel ended up
ditching Stack-compatible middleware because they wanted to be able to
build the middleware from the container. Drupal 8 doesn't use Stack Builder
as they also want to be able to construct the middleware from the container
(Symfony's, in this case).
Any framework that has extensions, modules, bundles, plugins or whatever
that wants to implement PSR-15 middleware is likely going to want to allow
the extensions, modules, bundles, plugins or whatever to provide middleware
without requiring the application to manually configure the middleware.
This is a bold statement, and feel free to call me out on this, but
experience in this domain has shown me that this is the case.
I'm probably also biased. I'll admit that.
As for a real-world and easy-to-consume example of this in action for a
primitive PSR-7 framework I put together a year and a half ago using
Laravel's container, it looked like this. It allowed the application to
register its own private middleware, it allowed for 3rd-party service
providers to add additional middleware, and it allowed for the core
framework to specify its core middleware.
class PrivateApiApp extends App
{
public function registerServiceProviders(Container $container)
{
parent::registerServiceProviders($container);
$container->tag(UserAuthentication::class,
WebApp::MIDDLEWARE_EARLY);
$container->tag(OrganisationAuthorization::class,
WebApp::MIDDLEWARE_EARLY);
$container->tag(UserIdMetadataEnrichment::class,
WebApp::MIDDLEWARE_EARLY);
}
}
class RelayServiceProvider {
public function register(Container $container)
{
$container->bind(Relay::class, function (Container $container) {
/** @var RelayBuilder $relayBuilder */
$relayBuilder = $container->make(RelayBuilder::class);
$queue = array_merge(
[
$container->make(NikicFastRoute::class, [
'actionAttributeName' =>
WebApp::ACTION_ATTRIBUTE_NAME,
'parametersAttributeName' =>
WebApp::PARAMETERS_ATTRIBUTE_NAME,
]),
],
$container->tagged('nimble.middleware.error_handler'),
$container->tagged('nimble.middleware.early'),
$container->tagged('nimble.middleware'),
$container->tagged('nimble.middleware.late'),
[
$container->make(ResponseAssertion::class),
$container->make(ViewTransformer::class),
$container->make(ActionHandler::class, [
'actionAttributeName' =>
WebApp::ACTION_ATTRIBUTE_NAME,
]),
]
);
return $relayBuilder->newInstance($queue);
}
}
}
--
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/81e9e337-2cf7-4336-a73e-bb4ae754ef40%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.