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.

Reply via email to